C/C++中的指针
时间:2010-06-03 来源:wy926834
C和C++的指针是有区别的:
C的指针有两种:指向数据,指向函数;C++的指针有4种:指向数据,指向函数,指向成员数据和指向成员函数;为什么不分两种,指向数据和指向函 数,这个前2种和后2种不能一对一。可以这么分,指向非成员和指向成员,指向成员的简称成员指针。以下一一说明。
1,指向数据的指针
非常简单。例如:
int a = 100; |
2,指向函数的指针
函数名可以看成是一个单身函数对象,取值后是函数的入口地址,如:
void foo(int a) |
foo看成是一个类型是void (int)的单身对象,但是对名字foo取值后,它会退化成相应的指针类型void (*)(int)。注意那个括号不能少。当然如果对foo取地址也是这个类型(取两次?没考虑过~~哇靠~太绝了吧)。
所以指向函数的指针,申明起来比较怪,像这样:
void (*pf)(int) = &foo; |
int foo2(float a,double b) |
函数指针的使用,两种方式:
(*pf)(100);
即,先引用*,打括号,再传实参调用,或者直接,pf(100)。
函数指针的意义:一个函数可以看成是一个策略,对于一个问题,可以采用不同的策略和方法,这种对策略的选择推迟到运行期,即用一个变量保存起来,在 程序跑起来的时候,决定使用什么策略,其本质即是动多态,对一个函数的调用延迟到运行时决定。
3,指向成员数据的指针
在要说成员指针之前,要先明确一个概念:名称的受限。C++有一套自己的名称查找机制,一个名称可以是一个类名,对象名,函数名等。受限是指是否 用::,->,.中的一种符号作用。
看一般的成员数据访问:
struct A{int a;}; |
当然类A的定义和下面三条语句不是在一起的,a.a是正确的名称,第一个a没有受限,指对象a,第二个a受限了,是在一个前提下进一步指成员 A::a,这里就是a的成员A::a。再举个例子:
struct A |
template<typename T>
class V
{
};
的this是V<T>*类型的。
转到正题。成员指针实质上是成员数据的偏移。像这样定义:
int A::*p;
它不能直接指向一个数据,因为它必须要是一个受限的名称,它只能指向一个类的成员,它像这样赋值和初始化:
p=&A::a;
它不能单独使用,因为单独使用的时候是非受限的,要先定义一个A的对象,再限制使用:
A a(100);
cout<<a.*p<<endl;
它必须放在一个限制式的右边。用几个例子来说明一下:
A a(100); |
4,指向成员函数的指针
如果(3)弄清楚了这个也应该很明白了,成员函数默认绑定this指针,即成员函数名也是一个受限的名称。它的定义和一般的函数定义类似,只是在指 针前加上一个类名和::。
struct A |
为什么不能默认使用pf呢?pf是A的成员,按理说会有隐含的this->在前面,如果foo()里换成:(*pf)(0);,会编译错误。 原因是,pf是成员,但*pf不是,如果像后者那样调用,它相当于:(*(this->pf))(0)。直接引用了成员指针。
另外,static成员数据和成员函数不能用成员指针,它们不认为是对象的一部分,它们可以直接用一般指针访问,当然它们也是受限的名称,但是受一 个类名限制和对象名无关。