C++指针及引用

来源:《C++必知必会》

1,引用。

引用与指针的三大区别:1,不存在空引用;2,所有引用都要初始化;3,一个引用永远指向用来对它初始化的那个对象。

编译器可能无法检测到不那么明显的创建空引用的尝试,如下:

1 Employee *getAnEmployee();
2 //......
3 Employee &anEmployee = *getAnEmployee();//getAnEmployee可能返回为空指针
4 if( &anEmployee == 0){
5 //......
6 }
7 //建议使用指针来存放getAnEmployee函数的返回值

2,我们知道,数组形参会产生所谓的“退化”现象,即退化成指向中其首元素的指针,而且会丢失边界。如以下函数声明:

void average(int ary[]);

其形参仍为一个int *类型。

如果数组边界的精确数值非常重要,并且希望函数只接受含有特定数量的元素的数组,可以考虑使用一个引用形参:

void average (int (&ary)[12]);

这样average函数即只能接受大小为12的整形数组。可通过模板来让编译器帮我们推导数组的大小:

template <int n>
void average(int (&ary)[n]);

更传统的做法当然是直接将数组大小以参数的形式传入:

void average_n(int ary[], int size);

多维数组形参的情况类似:

1 void process(int (*ary)[20]);//参数为指向20个元素数组的指针
2 void process(int ary[][20]);//与上行等价,但可读性更好

3,注意到引用与指针的第三个区别,所以在实际情况下,通常用引用来代替常量指针的使用:

1 T *pt = new T;
2 const T &rct = *pt;
3 T &rt = *pt;

4,使用多级指针的一种情况是在函数中修改指针参数的值,如:

1 void scanTo(const char **p, char c){
2 while( **p && **p != c)
3 ++*p;
4 }

这种做法是合理的,但是在C++中,更习惯、更简单、更安全的做法是使用指向指针的引用来作为函数参数,而不是指向指针的指针:

1 void scanTo ( const char *&p, char c){
2 while (*p && *p != c)
3 ++p;
4 }
5
6 char s[] = "Hello, China!";
7 const char *cp = s;
8 scanTo(cp, ",");

5,一个常见的误解是:适用于指针的转换同样适用于指向指针的指针。非也。如下:

1 Circle *c = new Circle;
2 Shape *s = c; //挺好的
3 Circle **cc = &c;
4 Shape **ss = cc; //错误!一个指向Circle指针的指针并不是一个指向Shape指针的指针!

当涉及const时也会发生同样的混淆:

1 char *s1 =0;
2 const char *s2 = s1; // no pblm
3 char *a[MAX]; // that is, char **
4 const char ** ps = a; //Oooooops!

总结:引用比指针安全、优美,能用引用的时候就尽量多用引用吧。

posted on 2011-05-24 07:56  Joshua Leung  阅读(293)  评论(0)    收藏  举报

导航