指向引用的指针和指针引用之间的区别

42 c++ memory pointers reference

指向引用的指针,指针的引用和C++中指针的指针有什么区别?

一个人应该优先于另一个?

Ara*_*raK 54

首先,对指针的引用就像对任何其他变量的引用:

void fun(int*& ref_to_ptr)
{
    ref_to_ptr = 0; // set the "passed" pointer to 0
    // if the pointer is not passed by ref,
    // then only the copy(parameter) you received is set to 0,
    // but the original pointer(outside the function) is not affected.
}
Run Code Online (Sandbox Code Playgroud)

指向引用的指针在C++中是非法的,因为-unlike指针 - 引用只是一个允许程序员创建其他别名的概念.指针是内存中具有其他地址的地方,但引用不是.

如果你坚持将引用作为指针处理,那么最后一点可能不是很清楚.例如:

int x;
int& rx = x; // from now on, rx is just like x.
// Unlike pointers, refs are not real objects in memory.
int* p = &x; // Ok
int* pr = ℞ // OK! but remember that rx is just x!
// i.e. rx is not something that exists alone, it has to refer to something else.
if( p == pr ) // true!
{ ... }
Run Code Online (Sandbox Code Playgroud)

从上面的代码中可以看出,当我们使用引用时,我们不会处理与它所引用的内容分离的内容.因此,引用的地址只是它所引用的地址.这就是为什么没有这样的东西称为所谈论的参考地址.

  • 最重要的一点(如您所表达的)是您可以**不** 获取指向引用(或对引用的引用)或类似内容的指针。由于引用只是另一个对象的别名。 (2认同)
  • 好的,但是您刚刚指向了一个参考: int* pr = ℞ 你能解释一下吗? (2认同)
  • @Mateusz:不,不是。它使用对对象(`x`)的引用(`rx`)来获取指向该对象的指针。它不是指向参考的指针。 (2认同)

Leo*_*Hat 44

指向指针的指针

C++中的指针只是一个存储内存位置的值(通常为32位值).

假设您有一个用户输入整数值(78== 0x4E十六进制).

它将以与此类似的方式存储在内存中(我故意简化此示例中的内容):

Memory address    Value
0x12345678        0x0000004E
Run Code Online (Sandbox Code Playgroud)

如果你想创建一个指向这个值的"指针",它在内存中看起来像这样:

Memory address    Value
0x22334455        0x12345678
Run Code Online (Sandbox Code Playgroud)

在内存地址,0x22334455您现在有一个"指针",其值为0x12345678,或者存储用户输入整数值(0x4E)的内存地址.

假设您想要为此指针值创建一个"指针".它看起来像这样:

Memory address    Value
0x11335577        0x22334455
Run Code Online (Sandbox Code Playgroud)

您现在在内存中有一个新的"指针"值,它存储以前定义的指针值的内存地址.

指针可以这样创建无限期-关键是要记住的是一个指针是编译器解释为存储器位置只是另一个值(它提供各种访问语义诸如*->其是特殊到"指针"类型).

引用指针

参考可以被认为是一个视图,或别名,到另一个真实对象.当您创建对被调用指针的引用时myReference,您只需定义一个名称myReference,该名称可用于访问先前在内存中定义的指针.

在内部,引用是使用指针实现的,但这超出了您的问题的范围.

引用对C++中的其他类型有限制 - 例如,在创建引用时,必须始终初始化引用"引用"实际对象,而指针可能指向无效或未初始化的内存.

指向参考的指针

这不存在.如前所述,引用仅仅是另一个对象的别名.您不能"指向"引用,因为它本身不是对象,而只是实际对象的另一个名称.

当然,您可以使用指向引用引用的对象的指针.但是现在我们回到了香草指针领域.

注意参数

当您通过将参数传递给方法或例程时,您实际上是将对象的"副本"传递给方法.当例程返回时,您对例程中的值所做的任何更改都将丢失,因为该参数将在例程的上下文中被视为局部变量.

如果要修改传入的参数,以便客户端(调用)代码可以访问更改,则必须通过指针引用传递参数.

例如:

void myMethod(int myValue)
{
    // NOTE: This change will be lost to the caller!
    myValue = 5;
}

void myMethod2(int* myValue)
{
    // Correct way of modifying pointer parameter value
    *myValue = 5;
}

void myMethod3(int& myValue)
{
    // Correct way of modifying reference parameter value
    myValue = 5;
}
Run Code Online (Sandbox Code Playgroud)

现在让我们说你的方法想要为指针分配内存.你可能想要这样做:

void myMethod4(int* myValue)
{
    // Warning: You will lose the address of the allocated
    // memory when you return!
    myValue = new int[5];
}
Run Code Online (Sandbox Code Playgroud)

但请记住,您在这里修改指针值的副本,而不是真正的指针值.由于您希望修改此例程中的指针,而不是指针"指向" 的,因此需要将其作为"指针指针"或"指针指针"传递:

void myMethod5(int** myValue)
{
    // Correct way of allocating memory in a method
    // via pointer-to-pointer
    *myValue = new int[5];
}

void myMethod6(int*& myValue)
{
    // Correct way of allocating memory in a method
    // via reference-to-pointer
    myValue = new int[5];
}
Run Code Online (Sandbox Code Playgroud)

在这些底2个的例子中,代码被调用myMethod5myMethod6通过将正确地得到新分配的存储器的存储器地址myValue的参数的指针或引用.

  • “在创建真实对象时,必须始终初始化引用以“引用”真实对象”实际上并非如此。您可以先发制人地将引用绑定到对象将来将占用的位置。在对象处于完全构造状态之前,您不能允许左值到右值的转换。示例:您可以使用成员变量的地址调用基类构造函数。构造顺序规定该成员尚不存在,但是存储对它的引用是完全合法的。 (2认同)

小智 10

没有指向引用的指针.


McP*_*inM 5

引用是远离指针的抽象.参考文献有点难以搞砸,特别是对于初学者来说,并且有点高级别.

不需要参考.你总是可以使用指针.但是,有时代码可以更容易阅读.

典型的初学者示例是链接列表.想象一下,你有一个名为"list"的变量,它包含指向第一个的指针.如果你想在头部添加一些东西,你需要给你的add()一个双指针,因为它需要能够修改"head".但是,您可以使用对指针的引用.在这里,我们希望在列表中使用指针,因为我们将对它们进行改变,但是如果我们传入对列表头部的引用而不是双指针,则add()函数将更清晰.

它们只是一种风格选择.如果您正在开发一个更大的项目,那么您应该采用项目的风格.如果没有,你可以使用你认为更好的任何东西.但是,如果您希望成为一名成功的C++程序员,那么您应该习惯使用所有样式.

您也不能拥有指向引用的指针.这是因为引用实际上只是另一个变量的另一个名称,可能在其他一些范围内.指向引用的指针没有意义.你真正想要的只是指向原始数据的指针,不涉及任何引用.