我对在某些情况下是否选择值语义或引用语义没有感觉(但我希望如此)。有什么我可以应用的经验法则吗?

我通常会选择除内置数据类型(char、int、bool、double 等)以外的所有内容的引用。但是,有时无法从函数返回引用,因此我必须使用指针。下面的函数就是一个例子:

Foo bar()
{
    Foo f;
    f.do_stuff();
    return f;
}

我会使用 boost::shared_ptr 来存储 Foo 对象,但这使得使用该对象变得非常难看。我目前正在研究一个返回双端队列的函数,该双端队列几乎不会超过 10 个元素(这是我的假设,我无法确定)。按值返回可以吗?我的考虑是否属于过早优化的情况?

有帮助吗?

解决方案

按值返回是可以的,因为大多数编译器都会优化额外的副本(这称为返回值优化,或者在您的情况下命名为返回值优化)。

但是惯用方式是

void bar(Foo& out)
{
   out.do_stuff();
}

其他提示

无论如何,不​​要 返回 堆栈上分配的任何内容(即局部变量,例如这里的 f)通过引用或指针。

您可以随时这样做:

Foo& bar(Foo& f)
{
    f.do_stuff();
    return f;
}

并这样使用:

Foo f;
bar(f);

这里的缺点是您不能保证 bar() 将收到新的 Foo 目的。如果这很重要,则必须对此进行修改:

Foo& bar(Foo& f)
{
    f = Foo();
    f.do_stuff();
    return f;
}

但是,如果确实获得了新副本,则将有不必要的初始化。或者,您可以简单地检查 fdoSomething() 如果不符合期望,请提出异常。

当您想维护任何变量或对象的状态时使用参考(即通过调用例程在变量/对象上完成某些procesisng之后,将相同的变量与调用例程进行相同的变量),并且在将大数据传递给功能否则将有大量数据的双副本。

同样,在某些情况下,需要防止对象复制位,在这种情况下,我们将类的复制构造函数作为私有。

我的正常规则是:

  1. 始终按价值使用通过。

    简单,嗯?参考吸吮。他们永远不应该引入。

  2. 如果您有“类似数据结构”,则将其传递。如果您有“类似数据结构”的“对象”传递指针(参考语义,请按值传递)。

    通常很清楚哪种类型是:值或对象。如果您可以将其变异,它是一个对象。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top