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
59
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 the main reason you'd prefer one over the other.
- 不能将NULL赋值给引用。这是一个关键的区别,也是你喜欢其中之一的主要原因。
- When you take the address of a pointer, you get the address of the pointer variable. When you take the address of a reference, you get the address of the variable being referred to.
- 当你取指针的地址时,你会得到指针变量的地址。当您获取引用的地址时,您将获得所引用变量的地址。
- You can't reassign a reference. Once it is initialized it points to the same object for its entire life.
- 你不能重新分配一个参考。初始化之后,它将在整个生命周期中指向同一个对象。
#2
13
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:
一些关于为什么你想要使用其中一个的问题:
- Difference between pointer and reference
- 指针和引用之间的区别
- Are there any benefits of passing by pointer over reference?
- 通过指针传递引用有什么好处吗?
- Pointer vs. Reference
- 指针与引用
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
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对象)用作引用初始化中的rvalue。我不确定我的术语是否正确……
#6
3
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刚刚发表了一篇关于指针/引用的优秀文章,我认为我应该给你们指出来。
#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's significant since there is no "undefined" or "invalid" reference value.
不能将NULL赋值给引用(shoosh提到了这一点):这很重要,因为没有“未定义”或“无效”的引用值。
-
You can pass a temporary variable as a const reference, but it's not legal to pass a pointer to 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.
- 获取一个变量的地址来获取指针会迫使编译器将其保存到内存中。为局部变量赋值只创建同义词;在某些情况下,这可能允许编译器将数据保存在寄存器中,并避免加载-hit-store。然而,这只适用于局部变量——一旦通过引用作为参数传递,就无法避免将其保存到堆栈中。
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.
类似地,__limit关键字不能应用于引用,只有指针。
-
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
59
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 the main reason you'd prefer one over the other.
- 不能将NULL赋值给引用。这是一个关键的区别,也是你喜欢其中之一的主要原因。
- When you take the address of a pointer, you get the address of the pointer variable. When you take the address of a reference, you get the address of the variable being referred to.
- 当你取指针的地址时,你会得到指针变量的地址。当您获取引用的地址时,您将获得所引用变量的地址。
- You can't reassign a reference. Once it is initialized it points to the same object for its entire life.
- 你不能重新分配一个参考。初始化之后,它将在整个生命周期中指向同一个对象。
#2
13
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:
一些关于为什么你想要使用其中一个的问题:
- Difference between pointer and reference
- 指针和引用之间的区别
- Are there any benefits of passing by pointer over reference?
- 通过指针传递引用有什么好处吗?
- Pointer vs. Reference
- 指针与引用
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
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对象)用作引用初始化中的rvalue。我不确定我的术语是否正确……
#6
3
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刚刚发表了一篇关于指针/引用的优秀文章,我认为我应该给你们指出来。
#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's significant since there is no "undefined" or "invalid" reference value.
不能将NULL赋值给引用(shoosh提到了这一点):这很重要,因为没有“未定义”或“无效”的引用值。
-
You can pass a temporary variable as a const reference, but it's not legal to pass a pointer to 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.
- 获取一个变量的地址来获取指针会迫使编译器将其保存到内存中。为局部变量赋值只创建同义词;在某些情况下,这可能允许编译器将数据保存在寄存器中,并避免加载-hit-store。然而,这只适用于局部变量——一旦通过引用作为参数传递,就无法避免将其保存到堆栈中。
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.
类似地,__limit关键字不能应用于引用,只有指针。
-
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.
这些函数显然不是“相同的”,但对于虚拟行为,它们的行为也类似。关于切片,这只发生在处理值时,而不是处理引用或指针。