在所有情况下更喜欢C++引用指针是否真的是最佳做法?

Fip*_*ipS 13 c++

C++ FAQ说:

"尽可能使用引用,并在必要时使用引用."

我觉得它不像上面说的那么容易.已经很好地讨论了引用通常对指针更好的原因.所以我宁愿讨论特殊情况,其中引用有意义,但非常不寻常,只是感觉不对:

对我来说,最明显的情况是它们在一般数据结构(如树或链表)中的使用.他们的接口当然可以使用引用来实现并且感觉更安全,但是我还没有看到可以利用引用的单个实现,例如:

Node *parent = n.parent(); // parent might be unset -> pointer
Node &child = n.child(5); // child is always valid -> reference
Run Code Online (Sandbox Code Playgroud)

虽然它看起来很有吸引力,但它会导致代码如下:

if(parent == &child) ... //  weird, unusual at least?
Run Code Online (Sandbox Code Playgroud)

我想知道,这是什么代表纯C++?

每当我试图在任何可能的地方盲目地使用引用时,我都会遇到各种类似的不一致,并最终以各种丑陋的方式混合指针和引用.

总而言之,为什么operator new不首先返回对新实例的引用而不是指针?(并在出现错误时抛出):

Node &n = new Node;
delete &n;
Run Code Online (Sandbox Code Playgroud)

这是一个荒谬的例子,但这不是"纯粹的C++"吗?

Sen*_*abu 11

初始化后,无法修改引用以引用其他对象.但是可以修改指针以在运行时引用不同的对象.

一般的经验法则

每当您希望变量在其生命周期内指向不同的对象时,请使用指针.

如果您只想将变量用作另一个变量的别名,请使用引用.

作为参数

我们有时将参数作为引用传递(const/non-const).每次调用函数时,这都有助于避免复制整个对象.因此,当传递大尺寸的物体时,这将是非常有意义的.

如果函数需要接收一些参数而不是可选的null,则可以使用指针.但是,同样,您可以始终为任何类定义静态null对象,并且可以使用它.

作为返回值

每当我们重载诸如[]或<<之类的运算符时,我们都会返回引用.这是因为,如果我说,vec [0] = 10,它实际上应该将值10分配给vec中的位置0.由于显而易见的原因,我不能不使用指针.*vec [0] = 10不会看起来不错.此外,您应该保证,当您返回引用时,它始终引用一个对象(它永远不应该为null).

同样,当函数可以返回NULL值时,使用指针,否则您可能必须为该类声明一个静态null对象.

作为数据成员

引用应该在构造函数中初始化.因此,一旦构造了对象,就不能改变它们.

因此,如果您需要一个在类的生命周期中需要指向不同对象的变量,那么指针将是一个不错的选择.


Dre*_*all 6

我认为通用数据结构属于"必要时使用指针"子句.也就是说,由于引用是常量(即它们总是引用同一个对象),因此使用链接列表或树节点结构中的引用将意味着您无法插入新节点或从数据结构中删除旧节点 - 通常会失败目的.

正如有人在评论中所说,我认为这个建议确实适用于函数参数.传递引用而不是指针避免了必须为每个函数添加空指针处理逻辑,这在代码大小和清晰度方面带来了许多好处.


Rad*_*avu -5

“new”运算符分配内存(就像 C 中的 malloc 一样)。由于 C++ 没有实现垃圾收集器(如 Java 或 C#),因此您可能会耗尽内存。因此,当new分配内存失败时返回NULL值。这样就可以测试分配是否成功。

不能将引用与 new 运算符一起使用,因为可能会因内存不足而分配 NULL 值。

  • *因为 C++ 没有实现垃圾收集器(如 Java 或 C#),您可能会耗尽内存* [暗示 Java 不能耗尽内存?](http://www.google.com.au/webhp? sourceid=chrome-instant&amp;ie=UTF-8&amp;ion=1#hl=en&amp;sugexp=frgbld&amp;gs_nf=1&amp;cp=14&amp;gs_id=2&amp;xhr=t&amp;q=java.lang.outofmemoryerror&amp;pf=p&amp;output=search&amp;sclient=psy-ab&amp;oq=java.lang.outo&amp;aq=0&amp;aqi=g4&amp;aql= &amp;gs_sm=&amp;gs_upl=&amp;gs_l=&amp;pbx=1&amp;bav=on.2,or.r_gc.r_pw.r_qf.,cf.osb&amp;fp=9ac572733e1be876&amp;biw=1920&amp;bih=979&amp;ion=1) (5认同)
  • `new` 不会返回 NULL,它会抛出异常。 (4认同)
  • `new` 不会返回 NULL,它会抛出 `std::bad_alloc`。要使“new”在分配失败时返回 NULL,您需要使用“std::nothrow”参数调用它。 (4认同)