c++之引用的本质
2016-04-18 19:34
295 查看
引用变量是c++引入的重要机制。
错误观念:引用本质只是别名,在符号表中ri和i对应于相同的变量地址
在底层实现上,引用是用指针常量实现的,如果用指针常量实现,反汇编是一毛一样的。引用和指针常量关系如下:
(1)内存中占用都是4字节,存放都是被引用对象的地址,都必须在定义的同时进行初始化。
(2)指针常量本身允许寻址;引用变量不允许寻址,&r返回的是被引用对象的地址,就是变量r中的值,而不是变量r的地址,r的地址由编译器掌握,程序猿无法直接对其进行存取。
(3)凡用引用的代码,都可以用指针常量实现;反之不然,因为引用本身限制较多,不能完成指针所有的操作。
例如下面的代码是合法的:
但是如下代码却是非法的:
虽然引用在初始化时会绑定一个变量,不过也是可以有特殊手段可以改变引用绑定关系:
答案输出:
&i == 003CF9D0
&j == 003CF9C4
&pi == 003CF9AC
&pj == 003CF9A0
dis == -12
3996112
3996100
i == 5
j == 666
因为在内存中排布方式是:
dis 低地址
addr
pj
pi
r
j
i 高地址
在
&j == 003CF9C4
&pi == 003CF9AC
中隔了2个dis,其实就是夹了一个r
错误观念:引用本质只是别名,在符号表中ri和i对应于相同的变量地址
int i=5; 0100437E mov dword ptr [i],5 int &ri=i; 01004385 lea eax,[i] 01004388 mov dword ptr [ri],eax ri=8; 0100438B mov eax,dword ptr [ri] ri=8; 0100438E mov dword ptr [eax],8
在底层实现上,引用是用指针常量实现的,如果用指针常量实现,反汇编是一毛一样的。引用和指针常量关系如下:
(1)内存中占用都是4字节,存放都是被引用对象的地址,都必须在定义的同时进行初始化。
(2)指针常量本身允许寻址;引用变量不允许寻址,&r返回的是被引用对象的地址,就是变量r中的值,而不是变量r的地址,r的地址由编译器掌握,程序猿无法直接对其进行存取。
(3)凡用引用的代码,都可以用指针常量实现;反之不然,因为引用本身限制较多,不能完成指针所有的操作。
例如下面的代码是合法的:
int i=5,j=6; int *const array[] = {&i,&j}; //指针数组
但是如下代码却是非法的:
int i=5,j=6; int &array[] = {i,j}; //不可能有引用的数组
虽然引用在初始化时会绑定一个变量,不过也是可以有特殊手段可以改变引用绑定关系:
int main() { //freopen("input.txt","r",stdin);\ int i=5,j=6; int &r = i; void *pi = &i,*pj = &j; int* addr; int dis = (int)pj-(int)pi; addr = (int *)((int)pj+dis); //精确计算r的地址 cout<<"&i == "; PRINT(pi); //i的地址 cout<<"&j == "; PRINT(pj); //j的地址 cout<<"&pi == "; PRINT(&pi); //pi的地址 cout<<"&pj == "; PRINT(&pj); //pj的地址 cout<<"dis == "; PRINT(dis); PRINT(*addr); //(*add)+=dis; (*addr)=(int)&j; PRINT(*addr); //将r指向j r=666; cout<<"i == "; PRINT(i); cout<<"j == "; PRINT(j); return 0; }
答案输出:
&i == 003CF9D0
&j == 003CF9C4
&pi == 003CF9AC
&pj == 003CF9A0
dis == -12
3996112
3996100
i == 5
j == 666
因为在内存中排布方式是:
dis 低地址
addr
pj
pi
r
j
i 高地址
在
&j == 003CF9C4
&pi == 003CF9AC
中隔了2个dis,其实就是夹了一个r
相关文章推荐
- c++实现数组和指针的快速排序
- C/C++易错问题分析
- java和c语言一些数组差别
- C++ WINDOWS API 第2章 Windows API概要
- C++ WINDOWS API 第1章 Windows 应用程序开发入门
- C++ 之 常量成员函数
- leetcode笔记:Power of Four
- C++计算代码片运行时间
- C++冒泡排序
- c++代码同步系统时间
- C语言中的隐式转换
- C++线程 基础教程
- 求最大公约数(c++)
- C++ Member Functions的各种调用方式
- 用C++ 实现复杂链表的复制
- C++STL中vector容器 begin()与end()函数、front()与back()的用法
- C++中的接口继承和实现继承
- [C++]函数对象(二)
- remove_if 的用法
- 1--C语言关键字