为什么引用类型和指针在编译代码中是相同的?(您可以在第三行和第四行看到)。我试图搞清楚,但显然我无法实现。
如果引用类型变量必须在声明时初始化并且不能更改,那么是否需要像指针那样进行间接?
int x = 10;
mov dword ptr [x],0Ah
int y = x;
mov eax,dword ptr [x]
mov dword ptr [y],eax
int &i = y;
lea eax,[y]
mov dword ptr [i],eax
int *p = &x;
lea eax,[x]
mov dword ptr [p],eax
p = &i;
mov eax,dword ptr [i]
mov dword ptr [p],eax
x = i;
mov eax,dword ptr [i]
mov ecx,dword ptr [eax]
mov dword ptr [x],ecx
答案 0 :(得分:2)
如果编译器知道引用始终引用单个特定对象/项,那么编译器当然可以优化间接。
但是,大多数引用实际上都是在运行时绑定的。即使引用的特定实例不能被反弹,包含引用成员的特定范围或对象的不同实例的不同执行也可以与针对这些实例中的每个实例的不同对象绑定的引用一起运行。使用间接是编译器处理此问题的一种方法。
引用只绑定到单个事物的情况可能相对不频繁,编译器可能不会寻找优化 - 特别是因为在大多数情况下优化不会是显着的增益。 / p>
此外,我怀疑你没有启用编译器优化 - 使用你的代码并使用y
和i
调用各种函数及其地址,这是VC ++ 2005中的一个快速测试,优化显示编译器没有将i
实现为指针,而是作为y
的真正别名(即,每当传递i
或&i
时,编译器使用{的地址直接{1}}。
如果您正在查看编译器的调试输出,那么它总是会将引用视为幕后指针而不会让您感到惊讶。
答案 1 :(得分:2)
引用只是限制指针。唯一的区别是它们必须指向现有变量。你可以在C ++中解决这个问题,但是很难错过:
int& r = *(reinterpret_cast<int*>(0x0));
当然这是未定义的行为!
所以,基本上它们是实现作为指针。它们在许多地方的使用不同,例如。当引用为r值或l值时,引用会自动退出:
int x = 0;
int& r = x; // 1) no need to take the address of x like &x
r = r * x; // Manually: (*r) = (*r) * x
它们为原始指针提供了更安全的替代方案。此外,它们具有比原始指针更优雅的语法。试想一下,在重载类操作符时没有引用。
总之,它们是受限制的指针,具有更好/更安全的别名但功能更少。
答案 2 :(得分:1)
引用在内部表示为指针。它是编译器,它限制了初始化和不可重复性。
如果必须是引用类型变量 在声明初始化,不能 被改变所以有任何需要做 像指针一样间接?
唯一的选择是复制值,这不是引用所做的。引用的作用类似于指针:它保存在对象的位置上。不同之处在于引用的作用类似于对象本身,而不需要明确地解除引用。
答案 3 :(得分:1)
C ++ FAQ lite为您所看到的内容提供了一个很好的解释:https://isocpp.org/wiki/faq/references
基本上,简而言之,编译器基本上将其视为指针,它使用对象的地址并为您解除引用。
答案 4 :(得分:0)
是的,引用只是指针的语法糖(具有适用于新语法的限制)。它还让C ++看起来具有copy-by-reference参数传递,而C只有按值复制(甚至是指针参数)