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

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

在哪里应该比另一个更受欢迎?

首先,对指针的引用就像对其他variables的引用:

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. } 

一个指向引用的指针在C ++中是非法的,因为不像一个指针,引用只是一个允许程序员别名的概念。 指针是内存中的地址,其他地址的地址,但引用不是。

现在最后一点可能不是很清楚,如果你坚持把引用作为指针来处理。 例如:

 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! // ie rx is not something that exists alone, it has to refer to something else. if( p == pr ) // true! { ... } 

从上面的代码可以看出,当我们使用引用的时候,我们并没有处理与引用的东西分离的东西。 所以,引用的地址就是它所指的地址。 这就是为什么没有这样的东西被称为参考的地址就在谈论什么。

指向指针的指针

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

假设您有一个用户input整数值(hex为78 == 0x4E )。

它将以类似的方式存储在内存中(我故意简化这个例子):

 Memory address Value 0x12345678 0x0000004E 

如果你想为这个值创build一个“指针”,它将在内存中看起来像这样:

 Memory address Value 0x22334455 0x12345678 

在内存地址0x22334455您现在有一个“指针”,其值为0x12345678 ,或者用户input整数值( 0x4E )的存储地址。

假设你想创build一个指向这个指针值的“指针”。 它看起来像这样:

 Memory address Value 0x11335577 0x22334455 

您现在在内存中有一个新的“指针”值,它存储了先前定义的指针值的内存地址。

指针可以像这样无限地创build – 关键是记住指针只是编译器解释为内存位置的另一个值(它提供了各种访问语义,比如“指针”types特有的*-> )。

引用一个指针

一个引用可以被看作是另一个真实对象的视图或别名。 当您创build一个名为myReference的指针的引用时,您只需定义一个名为myReference的新名称,该名称可用于访问先前在内存中定义的指针。

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

引用对C ++中的其他types有一定的限制 – 例如,当你创build一个引用时,你必须初始化一个引用来“引用”一个真实的对象,同时指针可能指向无效或未初始化的内存。

指向参考的指针

这不存在。 如前所述,引用仅仅是另一个对象的别名。 你不能“指向”一个引用,因为它本身不是一个对象,而只是一个真实对象的另一个名字。

当然,你可以有一个指向引用所引用的对象的指针。 但是现在我们回到了香草指针领域。

有关参数的说明

当你通过一个parameter passing一个参数给一个方法或例程时,你本质上是将该对象的“复制”传递给该方法。 例程返回时,对例程中的值所作的任何更改都将丢失,因为参数在例程的上下文中将被视为局部variables。

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

例如:

 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; } 

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

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

但请记住,您正在修改指针值的副本 ,而不是真正的指针值。 既然你想修改这个例程中的指针 ,而不是指针指向的 ,你需要把它作为“指向指针的指针”或者“指针的引用”来传递:

 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]; } 

在下面这两个例子中,调用myMethod5myMethod6的代码将通过myValue参数指针或引用正确地获取新分配的内存的内存地址。

不存在指向引用的指针。

一个引用是一个远离指针的抽象。 参考文献有点困难,特别是对于新手来说,并且更高一些。

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

一个典型的初学者例子是一个链表。 想象一下你有一个名为“list”的variables,它包含一个指向第一个的指针。 如果你想添加一些东西的头,你需要给你的add()一个双指针,因为它需要能够修改“头”。 但是,您可以使用对指针的引用。 在这里,我们希望在列表本身中使用指针,因为我们会对它们进行变异,但是如果我们传入一个引用而不是一个双指针,那么add()函数会更清晰。

他们只是一个风格的select。 如果你正在做一个更大的项目,那么你应该select项目的风格。 如果没有,你可以使用任何你觉得是可取的。 但是,如果你希望成为一个轻微成功的C ++程序员,那么你应该习惯于使用所有的风格。

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

需要注意的是,虽然引用不是一个对象,因此也没有可访问的地址,但引用可以包含在一个对象中,而包含的对象确实有一个地址。

 struct contains_ref { int& ref; contains_ref(int& target) : ref(target) {} }; 

“引用是别名”的解释并不正确,但往往伴随着误导性的说法。 引用不等同于原始对象。 它有自己的一生,由它所包含的范围或对象来决定,而不是它所指的对象。 一个引用可以超越一个对象,被用来引用在同一地址创build的新对象。

把一个引用当作真正的东西 – 一个围绕指针的抽象,它将null排除为一个有效的值,并防止重置1 – 而不是魔术。 不是从它的指针性质得出的引用的唯一不寻常的属性是临时对象的终生扩展。


1事实上,这是由于C ++没有提供任何引用引用本身而不是其目标的语法的结果。 所有的操作员,包括分配操作员,都被简单地应用到目标上。

试试看你自己究竟是什么东西。 示例程序只是输出一个int的值和不同实体的地址:

 #include<stdio.h> int main(){ int myInt ; int *ptr_to_myInt = &myInt; int *ptr_to_myInt_ref = ptr_to_myInt; myInt = 42; printf("myInt is %d\n",myInt); printf("ptr_to_myInt is %x\n",ptr_to_myInt); printf("ptr_to_myInt_ref is %x\n",ptr_to_myInt_ref); printf("&ptr_to_myInt is %x\n",&ptr_to_myInt); return 0; } 

输出:

 myInt is 42 ptr_to_myInt is bffff858 ptr_to_myInt_ref is bffff858 &ptr_to_myInt is bffff854 

所以,指向int的指针和指向int引用的指针是完全一样的东西。 这从代码中是显而易见的,因为指向一个引用的指针只是另一种对指针进行别名的方法(它是说“为我保留下面的地址”)。

现在,指针在内存中还需要一些空间,如果你打印这个指针的引用(最后一个printf语句),它只是指示指针所在的内存的位置。