如何使用指针实现C ++中的引用

时间:2014-08-09 19:42:57

标签: c++ pointers reference

我听说C ++引用变量是使用指针实现的。在我开始使用C ++之前,我一直在寻找一些C代码,因为我希望能够在C语言中找到与之相关的东西。有没有人真的有一个关于如何使用指针实现它的例子?

我一直在研究这个问题,这就是我发现的。但是,我不确定它是否合法,因为我以前无法在C ++文件中正确运行。任何答案将不胜感激,谢谢! :)

int& =  *(int const *)

4 个答案:

答案 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的地址,就像它是一个指针一样。差异很微妙,但具体。