指针和引用参数之间的区别?

发布于 2024-07-15 05:25:27 字数 357 浏览 3 评论 0原文

这些是否相同:

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

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

忽略空指针的可能性。 无论 someInt() 是虚拟的还是传递一个 barbar 的子类,这两个函数在功能上是否相同?

这个切片有什么作用吗:

bar& ref = *ptr_to_bar;

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?

Does this slice anything:

bar& ref = *ptr_to_bar;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

稀香 2024-07-22 05:25:27

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

还有一些差异:

  • 您不能将 NULL 分配给引用。
    这是一个至关重要的区别
    您更喜欢其中一个的主要原因
    其他。
  • 当你获取一个地址时
    指针,你得到的地址
    指针变量。 当您采取
    引用的地址,你得到
    变量的地址是
    提到的。
  • 您无法重新分配参考。 一旦它被初始化,它在整个生命周期中都指向同一个对象。

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.

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.
  • 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.
偏爱你一生 2024-07-22 05:25:27

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

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

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

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

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.

笔芯 2024-07-22 05:25:27

引用是一个常量指针,即,您不能更改引用以引用其他对象。 如果更改,引用对象的值也会更改。

例如:

       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

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
书信已泛黄 2024-07-22 05:25:27

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

查看语义差异也很重要:

  • 当您实际正常传递对象时,请使用引用 - 但它太大,因此传递对对象的引用而不是制作副本更有意义(如果您不修改的对象)。
  • 当您想要处理内存地址而不是对象时,请使用指针。

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.
夢归不見 2024-07-22 05:25:27

我已经很长时间没有使用 C++ 了,所以我什至不会尝试真正回答你的问题(抱歉); 然而,Eric Lippert 刚刚发布了一篇优秀文章 关于我认为应该向您指出的指针/引用。

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.

朕就是辣么酷 2024-07-22 05:25:27

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

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

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

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

柠檬色的秋千 2024-07-22 05:25:27

正如其他人所提到的,在实现中引用和指针基本上是相同的。 有一些小警告:

  • 您不能将 NULL 分配给引用
    (shoosh提到了这一点):那就是
    很重要,因为没有
    “未定义”或“无效”引用
    值。

  • 您可以通过临时
    变量作为 const 引用,
    但传递指针是不合法的
    到一个临时的。

例如,这是可以的:

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

void bar( ) 
{
  foo( Thingy(1,2) );
}

但大多数编译器会抱怨

void foo2( Thingy * a);

void bar2()
{
  foo( &Thingy(1,2) );
}
  • Takeing a address of a variable to get a point 强制编译器将其保存到内存中。 将引用分配给局部变量只是创建一个同义词; 在某些情况下,这可能允许编译器将数据保留在寄存器中并避免 加载命中存储。 然而,这仅适用于局部变量——一旦通过引用将某些内容作为参数传递,就不可避免地将其保存到堆栈中。

 

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) );
}
  • 同样,__restrict 关键字 不能应用于引用,仅应用于指针。

  • 你不能用引用进行指针算术,所以如果你有一个指向数组的指针,那么数组中的下一个元素可以通过 p+1 获得,而引用在其整个生命周期中只指向一个事物.

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.

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

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.

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

著墨染雨君画夕 2024-07-22 05:25:27

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文