大学IT网 - 最懂大学生的IT学习网站! QQ资料交流群:367606806
当前位置:大学IT网 > C++技巧 > C++的那些事:你真的了解引用吗

C++的那些事:你真的了解引用吗(2)

关键词:C++引用  阅读(962) 赞(20)

[摘要]本文是对C++的那些事:你真的了解引用吗的讲解,与大家分享。

这个问题其实要从C++底层机制谈起,C++为我们提供的各种存取控制仅仅是在编译阶段给我们的限制,也就是说编译器确保了你在完成任务之前的正确行为,如果你的行为不正确,那么编译器就是给你在编译时提示错误。所谓的const和private等在实际的目标代码里根本不存在,所以在程序运行期间只要你愿意,你可以通过内存工具修改它的任何一个变量的值。

这也就解释了为什么上面的两段代码中引用和指针的汇编代码完全一致。

C++设计引用,并用常量指针来从编译器的角度实现它,目标是为了提供比指针更高的安全性,因为常量指针一旦与变量地址绑定将不能更改,这样降低了指针的危险系数,它提供了一种一对一的指针。

但是你觉得使用引用就安全了吗?它同样会有与使用指针一样的问题

 int *var = new int(42); 
 int &ref = *var; 
 delete var; 
 ref = 42; 
 return 0;

上面这段代码就很不安全,因为ref引用的内存区域不合法。

为了进一步验证引用与指针在本质上的相同,我们看当引用作为函数参数传递时,编译器的行为:

 void Swap(int& v1, int& v2); 
 void Swap(int* v1, int* v2);
 
     int var1 = 1; 
 00A64AF8  mov         dword ptr [var1],1  
     int var2 = 2; 
 00A64AFF  mov         dword ptr [var2],2  
     Swap(var1,var2); 
 00A64B06  lea         eax,[var2]  
 00A64B09  push        eax  
 00A64B0A  lea         ecx,[var1]  
 00A64B0D  push        ecx  
 00A64B0E  call        Swap (0A6141Fh)  
 00A64B13  add         esp,8  
     Swap(&var1, &var2); 
 00A64B16  lea         eax,[var2]  
 00A64B19  push        eax  
 00A64B1A  lea         ecx,[var1]  
 00A64B1D  push        ecx  
 00A64B1E  call        Swap (0A61424h)  
 00A64B23  add         esp,8 

上面代码再次证明了,引用与指针的行为完全一致,只是编译器在编译时对引用作了更严格的限制。

四、引用占多大的内存空间

因为在在表达式中,使用引用实际上就像使用变量本身一样,所以直接用sizeof是得不到引用本身的大小的。

double var = 42.0; 
double& ref = var;

cout << sizeof var << endl;  // print 8 
cout << sizeof ref << endl;   // print 8

我们可以通过定义一个只含有引用的类来解决这个问题:

 class refClass{ 
 private: 
     double& ref; 
 public: 
     refClass(double var = 42.0) :ref(var){} 
 };
 
 cout << sizeof refClass << endl;  // print 4

所以结论就是引用和指针一样实际占内存空间4个字节。

«上一页12下一页»


相关评论