从语义上理解,引用就是变量的别名,指针是一个变量,保存着变量的地址
因为引用是别名,所以引用不能单独存在,没有空引用,而能有空指针
但作为C++程序员,只从这个层面理解引用显然心里会发虚
因此上测试代码
#include <iostream> void t1() { char c = ‘a‘; char &r = c; char *p = &c; r = ‘b‘; *p = ‘c‘; int size; size = sizeof(r);//1 size = sizeof(p);//1 char *q1; q1 = &r; char **q2; q2 = &p; } #pragma pack(1) struct T2A { char &_r; char _c; }; #pragma pack() void t2() { char c = ‘a‘; T2A s1{ c, ‘b‘ }; void *p; p = &s1; p = &s1._r; p = &s1._c; int size; size = sizeof(s1);//size值是5 } void main() { t1(); t2(); system("pause"); }
代码本身没什么意思,有意思的是反汇编的结果
t1的反汇编
char c = ‘a‘; 00F61728 mov byte ptr [c],61h char &r = c; 00F6172C lea eax,[c]00F6172F mov dword ptr [r],eax //引用r实际上是一个dword ptr类型 char *p = &c; 00F61732 lea eax,[c] 00F61735 mov dword ptr [p],eax //指针p看起来是不是和引用r在内存布局上一模一样? r = ‘b‘; 00F61738 mov eax,dword ptr [r] 00F6173B mov byte ptr [eax],62h *p = ‘c‘; 00F6173E mov eax,dword ptr [p] 00F61741 mov byte ptr [eax],63h //赋值操作,引用和指针也是一模一样 int size; size = sizeof(r); 00F61744 mov dword ptr [size],1 //但引用是一个语法糖,对引用操作的时候,编译器会把它换成被引用的对象 size = sizeof(p); 00F6174B mov dword ptr [size],4 char *q1; q1 = &r; 00F61752 mov eax,dword ptr [r] //取不到引用的地址,编译器给的是被引用对象的地址 00F61755 mov dword ptr [q1],eax char **q2; q2 = &p; 00F61758 lea eax,[p] 00F6175B mov dword ptr [q2],eax
t2反汇编
char c = ‘a‘; 00F640C8 mov byte ptr [c],61h T2A s1{ c, ‘b‘ }; 00F640CC lea eax,[c] //取c的地址 00F640CF mov dword ptr [s1],eax //s1的地址就是s1._r的地址,引用变量保存的是被引用对象的地址 00F640D2 mov byte ptr [ebp-18h],62h //ebp-18h是s1._c的地址 void *p; p = &s1; 00F640D6 lea eax,[s1] //取s1地址 00F640D9 mov dword ptr [p],eax p = &s1._r; 00F640DC mov eax,dword ptr [s1] //引用语法糖,想取s1._r的地址,实际上取到的是被引用对象c的地址 00F640DF mov dword ptr [p],eax p = &s1._c; 00F640E2 lea eax,[ebp-18h] 00F640E5 mov dword ptr [p],eax int size; size = sizeof(s1); 00F640E8 mov dword ptr [size],5 //引用变量_r 4字节,字符变量_c 1字节
由此可见,引用实际上是加了使用规则的指针
时间: 2024-10-24 05:47:25