指针和参考参数之间的区别?

时间:2021-06-25 13:30:00

Are these the same:

这些都是一样的:

int foo(bar* p) {  return p->someInt();}

and

int foo(bar& r) {  return r.someInt();}

Ignore the null pointer potential. Are these two functions functionally identical no matter if someInt() is virtual or if they are passed a bar or a subclass of bar?

忽略空指针潜力。这两个函数在功能上是否相同,无论someInt()是虚拟的还是传递到bar的bar或子类?

Does this slice anything:

这会切片吗:

bar& ref = *ptr_to_bar;

8 个解决方案

#1


61  

C++ references are intentionally not specified in the standard to be implemented using pointers. A reference is more like a "synonym" to a variable than a pointer to it. This semantics opens some possible optimizations for the compiler when it's possible to realize that a pointer would be an overkill in some situations.

有意在未使用指针实现的标准中指定C ++引用。引用更像是变量的“同义词”而不是指向它的指针。当有可能在某些情况下意识到指针过大时,这种语义会为编译器打开一些可能的优化。

A few more differences:

还有一些差异:

  • You can't assign NULL to a reference.This is a crucial difference and themain reason you'd prefer one over theother.
  • 你不能为引用分配NULL。这是一个至关重要的区别,也是你比其他人更喜欢的主要原因。

  • When you take the address of apointer, you get the address of thepointer variable. When you take theaddress of a reference, you get theaddress of the variable beingreferred to.
  • 获取apointer的地址时,将获得指针变量的地址。当您获取引用的地址时,您将获得所引用变量的地址。

  • You can't reassign a reference. Once it is initialized it points to the same object for its entire life.
  • 您无法重新分配参考。初始化后,它指向整个生命中的同一个对象。

#2


14  

Ignoring every syntactic sugar and possibilities that can be done with the one and not with the other and difference between pointers and references explained in other answers (to other questions) ... Yeah those two are functionally exactly the same! Both call the function and both handle virtual functions equally well.

忽略每个语法糖和可以用一个而不是另一个完成的可能性以及在其他答案中解释的指针和参考之间的差异(对于其他问题)......是的,这两个在功能上是完全相同的!两者都调用该函数并同时处理虚函数。

And no, your line does not slice. It's just binding the reference directly to the object pointed to by a pointer.

不,你的线不切片。它只是将引用直接绑定到指针指向的对象。

Some questions on why you would want to use one over the other:

关于为什么要使用一个而不是另一个的一些问题:

Instead of trying to come up with differences myself, i delegate you to those in case you want to know.

我不会自己想出差异,而是将你委托给那些你想知道的人。

#3


11  

Reference is a constant pointer i.e., you can't change the reference to refer to other object. If you change, value of the referring object changes.

引用是一个常量指针,即,您无法更改引用以引用其他对象。如果更改,引用对象的值将更改。

For Ex:

       int j = 10;       int &i = j;       int l = 20;       i = l; // Now value of j = 20       int *k = &j;       k = &l;   // Value of j is still 10

#4


5  

Yes they are functionally identical. Since a reference will require you to set it to an object before using it, you wont have to deal with null-pointers or pointers to invalid memory.

是的,它们在功能上是相同的。由于引用将要求您在使用它之前将其设置为对象,因此您不必处理空指针或指向无效内存的指针。

It is also important to see the semantical difference:

看到语义差异也很重要:

  • Use a reference when you would actually pass the object normal - but it is so large that it makes more sense to pass a reference to the object rather than making a copy (if you are not modifying the object that is).
  • 实际传递对象法线时使用引用 - 但是它太大以至于传递对象的引用而不是复制(如果你没有修改对象)更有意义。

  • Use a pointer when you want to deal with the memory address rather than with the object.
  • 如果要处理内存地址而不是对象,请使用指针。

#5


4  

I haven't used C++ in a long time, so I'm not even going to attempt to really answer your question (sorry); However, Eric Lippert just posted an excellent article about pointers/references that I figured I'd point you to.

我很久没有使用过C ++了,所以我甚至不打算真正回答你的问题(对不起);然而,Eric Lippert刚刚发布了一篇关于指针/参考文章的优秀文章,我认为我会指向你。

#6


4  

Not sure if anyone answered your 2nd question hidden at the bottom about slicing... no that won't cause slicing.

不确定是否有人回答了关于切片的隐藏在底部的第二个问题...不会导致切片。

Slicing is when a derived object is assigned (copied) to a base class object -- the derived class's specialization is "sliced" off. Note that I said the object is copied, we're not talking about pointers being copied/assigned, but the objects themselves.

切片是指将派生对象分配(复制)到基类对象时 - 派生类的特化是“切片”的。请注意,我说对象被复制了,我们不是在谈论被复制/分配的指针,而是对象本身。

In your example, that's not happening. You're just de-referencing a pointer to a Bar object (thereby resulting in a Bar object) being used as the rvalue in a reference initialization. Not sure I got my terminology right...

在你的例子中,这没有发生。您只是取消引用指向Bar对象的指针(从而导致Bar对象)被用作参考初始化中的右值。不确定我的术语是否合适......

#7


3  

As everyone else has mentioned, in implementation references and pointers are largely the same. There are some minor caveats:

正如其他人所提到的,在实现中,引用和指针大致相同。有一些小问题:

  • You can't assign NULL to a reference(shoosh mentioned this): that'ssignificant since there is no"undefined" or "invalid" referencevalue.

    你不能为引用分配NULL(shoosh提到这个):那是非常重要的,因为没有“未定义”或“无效”引用值。

  • You can pass a temporaryvariable as a const reference,but it's not legal to pass a pointerto a temporary.

    您可以将临时变量作为const引用传递,但将临时变量传递给临时变量是不合法的。

For example, this is okay:

例如,这没关系:

class Thingy; // assume a constructor Thingy(int,int)void foo(const Thingy &a){    a.DoSomething();}void bar( ) {  foo( Thingy(1,2) );}

but most compilers will complain about

但大多数编译器都会抱怨

void foo2( Thingy * a);void bar2(){  foo( &Thingy(1,2) );}
  • Taking the address of a variable to get a pointer forces the compiler to save it to memory. Assigning a reference to a local variable just creates a synonym; in some cases this may allow the compiler to keep the data on the register and avoid a load-hit-store. However, this only applies to local variables -- once something is passed as a parameter by reference, there's no avoiding saving it to stack.
  • 获取变量的地址以获取指针会强制编译器将其保存到内存中。分配对局部变量的引用只会创建一个同义词;在某些情况下,这可能允许编译器将数据保留在寄存器上并避免加载命中存储。但是,这仅适用于局部变量 - 一旦通过引用将某些内容作为参数传递,就无法避免将其保存到堆栈中。

 

void foo(){   int a = 5;   // this may be slightly more efficient   int &b = a;   printf( "%d", ++b );   // than this   int *c = &a;   printf( "%d", ++(*c) );}
  • Similarly, the __restrict keyword cannot be applied to references, only pointers.

    同样,__ restrict关键字不能应用于引用,只能应用于指针。

  • You can't do pointer arithmetic with references, so whereas if you have a pointer into an array then the next element in the array can be had through p+1, a reference only ever points at one thing in its entire life.

    你不能用引用做指针运算,所以如果你有一个指向数组的指针,那么数组中的下一个元素可以通过p + 1,一个引用只指向它的整个生命中的一件事。

#8


1  

The functions are obviously not "the same", but with regard to virtual behaviour they will behave similarly. Regarding slicing, this only happens when you deal withvalues, not references or pointers.

这些功能显然不是“相同”,但就虚拟行为而言,它们的行为类似。关于切片,这只发生在处理值时,而不是引用或指针。

#1


61  

C++ references are intentionally not specified in the standard to be implemented using pointers. A reference is more like a "synonym" to a variable than a pointer to it. This semantics opens some possible optimizations for the compiler when it's possible to realize that a pointer would be an overkill in some situations.

有意在未使用指针实现的标准中指定C ++引用。引用更像是变量的“同义词”而不是指向它的指针。当有可能在某些情况下意识到指针过大时,这种语义会为编译器打开一些可能的优化。

A few more differences:

还有一些差异:

  • You can't assign NULL to a reference.This is a crucial difference and themain reason you'd prefer one over theother.
  • 你不能为引用分配NULL。这是一个至关重要的区别,也是你比其他人更喜欢的主要原因。

  • When you take the address of apointer, you get the address of thepointer variable. When you take theaddress of a reference, you get theaddress of the variable beingreferred to.
  • 获取apointer的地址时,将获得指针变量的地址。当您获取引用的地址时,您将获得所引用变量的地址。

  • You can't reassign a reference. Once it is initialized it points to the same object for its entire life.
  • 您无法重新分配参考。初始化后,它指向整个生命中的同一个对象。

#2


14  

Ignoring every syntactic sugar and possibilities that can be done with the one and not with the other and difference between pointers and references explained in other answers (to other questions) ... Yeah those two are functionally exactly the same! Both call the function and both handle virtual functions equally well.

忽略每个语法糖和可以用一个而不是另一个完成的可能性以及在其他答案中解释的指针和参考之间的差异(对于其他问题)......是的,这两个在功能上是完全相同的!两者都调用该函数并同时处理虚函数。

And no, your line does not slice. It's just binding the reference directly to the object pointed to by a pointer.

不,你的线不切片。它只是将引用直接绑定到指针指向的对象。

Some questions on why you would want to use one over the other:

关于为什么要使用一个而不是另一个的一些问题:

Instead of trying to come up with differences myself, i delegate you to those in case you want to know.

我不会自己想出差异,而是将你委托给那些你想知道的人。

#3


11  

Reference is a constant pointer i.e., you can't change the reference to refer to other object. If you change, value of the referring object changes.

引用是一个常量指针,即,您无法更改引用以引用其他对象。如果更改,引用对象的值将更改。

For Ex:

       int j = 10;       int &i = j;       int l = 20;       i = l; // Now value of j = 20       int *k = &j;       k = &l;   // Value of j is still 10

#4


5  

Yes they are functionally identical. Since a reference will require you to set it to an object before using it, you wont have to deal with null-pointers or pointers to invalid memory.

是的,它们在功能上是相同的。由于引用将要求您在使用它之前将其设置为对象,因此您不必处理空指针或指向无效内存的指针。

It is also important to see the semantical difference:

看到语义差异也很重要:

  • Use a reference when you would actually pass the object normal - but it is so large that it makes more sense to pass a reference to the object rather than making a copy (if you are not modifying the object that is).
  • 实际传递对象法线时使用引用 - 但是它太大以至于传递对象的引用而不是复制(如果你没有修改对象)更有意义。

  • Use a pointer when you want to deal with the memory address rather than with the object.
  • 如果要处理内存地址而不是对象,请使用指针。

#5


4  

I haven't used C++ in a long time, so I'm not even going to attempt to really answer your question (sorry); However, Eric Lippert just posted an excellent article about pointers/references that I figured I'd point you to.

我很久没有使用过C ++了,所以我甚至不打算真正回答你的问题(对不起);然而,Eric Lippert刚刚发布了一篇关于指针/参考文章的优秀文章,我认为我会指向你。

#6


4  

Not sure if anyone answered your 2nd question hidden at the bottom about slicing... no that won't cause slicing.

不确定是否有人回答了关于切片的隐藏在底部的第二个问题...不会导致切片。

Slicing is when a derived object is assigned (copied) to a base class object -- the derived class's specialization is "sliced" off. Note that I said the object is copied, we're not talking about pointers being copied/assigned, but the objects themselves.

切片是指将派生对象分配(复制)到基类对象时 - 派生类的特化是“切片”的。请注意,我说对象被复制了,我们不是在谈论被复制/分配的指针,而是对象本身。

In your example, that's not happening. You're just de-referencing a pointer to a Bar object (thereby resulting in a Bar object) being used as the rvalue in a reference initialization. Not sure I got my terminology right...

在你的例子中,这没有发生。您只是取消引用指向Bar对象的指针(从而导致Bar对象)被用作参考初始化中的右值。不确定我的术语是否合适......

#7


3  

As everyone else has mentioned, in implementation references and pointers are largely the same. There are some minor caveats:

正如其他人所提到的,在实现中,引用和指针大致相同。有一些小问题:

  • You can't assign NULL to a reference(shoosh mentioned this): that'ssignificant since there is no"undefined" or "invalid" referencevalue.

    你不能为引用分配NULL(shoosh提到这个):那是非常重要的,因为没有“未定义”或“无效”引用值。

  • You can pass a temporaryvariable as a const reference,but it's not legal to pass a pointerto a temporary.

    您可以将临时变量作为const引用传递,但将临时变量传递给临时变量是不合法的。

For example, this is okay:

例如,这没关系:

class Thingy; // assume a constructor Thingy(int,int)void foo(const Thingy &a){    a.DoSomething();}void bar( ) {  foo( Thingy(1,2) );}

but most compilers will complain about

但大多数编译器都会抱怨

void foo2( Thingy * a);void bar2(){  foo( &Thingy(1,2) );}
  • Taking the address of a variable to get a pointer forces the compiler to save it to memory. Assigning a reference to a local variable just creates a synonym; in some cases this may allow the compiler to keep the data on the register and avoid a load-hit-store. However, this only applies to local variables -- once something is passed as a parameter by reference, there's no avoiding saving it to stack.
  • 获取变量的地址以获取指针会强制编译器将其保存到内存中。分配对局部变量的引用只会创建一个同义词;在某些情况下,这可能允许编译器将数据保留在寄存器上并避免加载命中存储。但是,这仅适用于局部变量 - 一旦通过引用将某些内容作为参数传递,就无法避免将其保存到堆栈中。

 

void foo(){   int a = 5;   // this may be slightly more efficient   int &b = a;   printf( "%d", ++b );   // than this   int *c = &a;   printf( "%d", ++(*c) );}
  • Similarly, the __restrict keyword cannot be applied to references, only pointers.

    同样,__ restrict关键字不能应用于引用,只能应用于指针。

  • You can't do pointer arithmetic with references, so whereas if you have a pointer into an array then the next element in the array can be had through p+1, a reference only ever points at one thing in its entire life.

    你不能用引用做指针运算,所以如果你有一个指向数组的指针,那么数组中的下一个元素可以通过p + 1,一个引用只指向它的整个生命中的一件事。

#8


1  

The functions are obviously not "the same", but with regard to virtual behaviour they will behave similarly. Regarding slicing, this only happens when you deal withvalues, not references or pointers.

这些功能显然不是“相同”,但就虚拟行为而言,它们的行为类似。关于切片,这只发生在处理值时,而不是引用或指针。