我听说C ++引用变量是使用指针实现的。在我开始使用C ++之前,我一直在寻找一些C代码,因为我希望能够在C语言中找到与之相关的东西。有没有人真的有一个关于如何使用指针实现它的例子?
我一直在研究这个问题,这就是我发现的。但是,我不确定它是否合法,因为我以前无法在C ++文件中正确运行。任何答案将不胜感激,谢谢! :)
int& = *(int const *)
答案 0 :(得分:2)
这是我能想到的最佳证明:
#include <iostream>
using namespace std;
double value;
struct pointer {
double *value; };
struct reference {
double& value; };
int main() {
pointer ptr { &value };
reference ref { value };
*ptr.value = 3.14;
cout << sizeof(value) << endl;
cout << sizeof(pointer) << endl;
cout << sizeof(reference) << endl;
cout << ref.value;
}
输出:
8 4 4 3.14
你能看到尺码吗? sizeof(pointer) == sizeof(reference)
但不是sizeof(value)
。
关于问题int& = *(int const *)
中的添加/编辑示例:
ref.value = *ptr.value; ref.value = *(double*)ref.value; //no const
ref.value = *(double const *)ptr.value; // yes, we can add const before *
int i = 1; const j = 2;
const int& cri = *(const int const *)&i; // same as *&i and simple i, notice two consts
const int& crj = j;
int& rj = j; // error: const cannot be removed that way
换句话说:引用是使用不同运算符集的常量指针(无法更改)。主要优点是编译器可以更好地优化它们(完全丢弃 引用/指针 ),但这并不能证明它们有任何不同,因为编译器可以优化/丢弃指针(以及gcc -O3可以做得很好,我已经看到并用指针反汇编好循环,其中gcc可以克服所谓的 别名问题 )。
答案 1 :(得分:2)
引用与常量指针具有相同的含义。
引用和指针的代码是相同的,至少对于MSVC2013。
例如:
int u=1,v=3, w;
int& x = u; // initialize reference
w = x; // x is synonym for u;
x++;
int *y = &u; // initalize pointer
w = *y; // y points to u
(*y)++;
在两种情况下都会生成初始化:
lea eax, DWORD PTR _u$[ebp]
mov DWORD PTR _x$[ebp], eax ; of course in the case of the pointe _y$ instead of _x$.
分配,在两种情况下都会生成:
mov eax, DWORD PTR _x$[ebp]
mov ecx, DWORD PTR [eax]
mov DWORD PTR _w$[ebp], ecx
即使增量也会生成相同的代码。
生成的代码是相同的,无论是指针,const指针还是const的poitner(在后一种情况下,++不起作用)。确保const为const是编译器的商业。
现在语法有一个细微差别:
int& x = u; // initialize reference
int *y = &u; // initalize pointer
int const *z = &u; // initialize pointer to "const int". Pointer itself is not const !
int * const a = &u; // initialize "const pointer" to "int", which is basically a reference.
有了这些定义:
//(*z)++; // invalid because the it points to a const int.
z = &w; // valid because pointer intself is not const
和:
(*a)++; // valid because the it points to an int.
// a = &w; // invalid because it's a const pointer
所以你可以说int&
几乎等同于int * const
(我这里不使用'=',因为它保留给operator =并且看起来像语法错误!)< / p>
当然,使用引用时,您总是使用其名称,就好像它是一个真实的变量(例如:x++
),而使用const指针时,您始终必须取消引用(又名:(*x)++
)。所以意思相同,但语法不同。
答案 2 :(得分:1)
编译器可以以任何可行的方式实现引用,包括某些引用已完全优化。
您可以思考参考
T& r = o;
作为
T* const pr = &o;
#define r (*pr)
这是对左值引用的大多数属性的一个很好的解释,除了这个概念图片不包括临时的生命周期扩展和临时初始化。
它“解释”那个
必须在声明中初始化引用,除非它是正式参数,
无法重新分配参考,
引用不能是有效代码中的“空引用”。
但请记住,它只是概念图:虽然它很可能是生成的代码的基本现实,但绝不是要求编译器实现引用这样。
您可能会发现section about references in the C++ FAQ具有指导意义。
答案 3 :(得分:0)
在C中,当您使用变量作为函数的参数时,它将按值发送。如果函数应该更改变量,则必须将参数作为指针发送。
int x = 5;
void addtwo(int* param)
{
*param += 2;
}
addtwo(&x); // This will send a pointer to x to the function addtwo
在C ++中,您可以发送参考:
void addtwo(int& param)
{
param += 2;
}
addtwo(x); // This will send a reference to x to the function addtwo
在这个简单的示例中,这看起来并没有什么区别,但在第二个示例中,看起来就像param没有被解除引用。但它确实是,因为它是作为参考发送的。即使param
看起来不像指针(并且它不是 - 它是一个引用),函数addtwo
也会被发送x的地址,就像它是一个指针一样。差异很微妙,但具体。