C++的优秀特性4:指针

(转载请注明原创于潘多拉盒子)

其实指针不是C++的特性,而是地地道道的C的特性。有人说C++继承了C的指针,实在是败笔,造成内存泄漏云云,纯粹是不懂。可以这么说,如果没有指针,C++会逊色很多,应用的场景也会大大缩小。

指针是一个变量,这个变量和一个int型的变量没有太大的不同,只是这个变量里存储的是它指向的对象的内存地址。

指针可以指向任何对象,包括内置类型(int、long、double、float等),对象类型,函数入口,甚至另外一个指针或者可以指向任何类型 。

涉及指针的操作符包括:定义指针(*)、解引用(*)、取地址(&)、取成员(->)、偏移解引用([]),偏移(+、-)、求偏移(-)。

先看看几种指针的例子:

  1. 指向int型变量的指针:int* p = new int(0);
  2. 指向对象的指针:Widget* p = new Widget();
  3. 指向函数的指针:int (*p)(int n) = factorial; 这里p是指向已经定义的函数factorial的函数指针。
  4. 指向指针的指针:Widget** pp = &p;
  5. 可以指向任何类型的指针:void* any = NULL; 这里的any是指向任何类型变量的指针。比如any = p; 或是any = pp; 甚至any = &pp; 都是合法的。

对于#1和#2的情况,大家应该已经比较熟悉,这里就不赘述了。

对于函数指针,在C语言实现动态方法绑定中非常有用。在C++中,更多的是通过接口虚函数覆盖(override)来代替。在某些兼容C程序动态行为绑定的例子中,可以采用函数指针。

比如我们可以根据用户输入的命令,定义对应的处理函数:

typedef bool (*command_process)(int argc, char** argv);

bool start(int argc, char** argv)
{
    // implementations
}

bool stop(int argc, char** argv)
{
    // implementations
}

bool write(int argc, char** argv)
{
    // implementations
}


bool read(int argc, char** argv)
{
    // implementations
}

// assign processors to names
std::map<std::string, command_process> processors;
processors["start"] = start;
processors["stop"] = stop;
processors["write"] = write;
processors["read"] = read;

// use processors to process commands
std::string command = "start";
processors[command](argc, argv);  // 调用名称“start”对应的处理函数,实现动态效果

  比较有意思的是可以指向任何类型的变量的指针,比如:

// 为了简单,这些变量全部定义在栈上,其实可以是new出来的
int n = 256;
double x = 3.14159265;
Widget w;

// 定义一个任意指针
void* any = NULL;

// 这个指针可以指向int类型的变量
any = &n;

// 也可以指向double型
any = &x;

// 或者是一个对象
any = &w;

// 但是,如果想对该指针解引用,则必须用reinterpret_cast
Widget* pw = reinterpret_cast<Widget>(any);

// 然后就可以调用了,安全性需要程序员自己保证,如果类型不对,程序可能crash。
pw->widgetMethod();

所以,除非非常必要,不要使用任意指针。  

指针是可以偏移解引用的,即使这个指针不是指向一个数组头部:p[i]等价于*(p+i)。这里的i不必是非负整数,还可以是负整数。比如p[-4]是合法的。

相同类型的指针之差是合法的,比如

int* begin = new int[100]; 
int* end = begin+100; 
int size = end - begin;     // 这是合法的,size = 100,表示begin和end之间的变量的个数

  

 

posted @ 2014-02-09 21:16  潘多拉盒子  阅读(498)  评论(0编辑  收藏  举报