建议26:用引用代替指针(1)
指针,可以通向内存世界,让我们具备了对硬件直接操作的超级能力。C++(www.cppentry.com)意识到了强大指针所带来的安全隐患,所以它适时地引入了一个新概念:引用。引用,从逻辑上理解就是“别名”,通俗地讲就是“外号”。在建立引用时,要用一个具有类型的实体去初始化这个引用,建立这个“外号”与实体之间的对应关系。
对于引用的理解与使用,主要存在两个的问题:
它与指针之间的区别。
未被充分利用。
引用并非指针。引用只是其对应实体的别名,能对引用做的唯一操作就是将其初始化,而且必须是在定义时就初始化。对引用初始化的必须是一个内存实体,否则,引用便成为了无根之草。一旦初始化结束,引用就是其对应实体的另一种叫法了。与指针不同,引用与地址没有关联,甚至不占任何存储空间。代码如下所示:
- int iNum = 12;
- int &rNum = iNum;
- int *pNum = &rNum; // 等同于int *pNum = & iNum;
- iNum = 2011; // rNum的值也为2011
由于引用没有地址,因此就不存在引用的引用、指向引用的指针或引用的数组这样的定义。据说尽管C++(www.cppentry.com)标准委员会已经在讨论,认为应在某些上下文环境里允许引用的引用。但那都是将来的事,至少现在不可以,将来的事谁又说得准呢?
因为是别名,与实体所对应,所以引用不可能带有常量性和可挥发性。所以,下面的代码在编译时会出现问题:
- int r = 10;
- int & volatile s = r;
- int & const m = r;
- volatile int& t = r;
- const int& n = r;
之所以说是出现问题,而不是错误,最主要的原因是各厂商编译器对于上述语法的容忍程度不同,有的会直接抛出错误并且编译失败,有的却只给出一个警告,比如:
gcc 4.3给出错误
- error: volatile/const限定符不能应用到'int&'上
VC++(www.cppentry.com) 2010给出警告- warning C4227: 使用了记时错误: 忽略引用上的限定符
对于加在引用类型前面的const或volatile修饰词,它们是符合编译器规则的,或者说被编译器选择性忽略了,没有什么问题(无error或warning)。而对于指针,上述使用绝对不存在任何的问题。
C阵营中那帮“顽固派”习惯在C++(www.cppentry.com)工程里使用指针,并且以此为傲,现在该是为引用翻身的时候了。先看一个简单的示例:
- void SwapData1(int a, int b)
- {
- int temp = a;
- a = b;
- b = temp;
- }
-
- void SwapData2(int* a, int* b)
- {
- int temp = *a;
- *a = *b;
- *b = temp;
- }
-
- void SwapData3(int& a, int& b)
- {
- int temp = a;
- a = b;
- b = temp;
- }