4

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

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

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

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

4

5 回答 5

3

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

于 2010-12-12T12:19:26.193 回答
3

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

但惯用的方法是

void bar(Foo& out)
{
   out.do_stuff();
}
于 2010-12-12T12:21:56.617 回答
0

你总是可以这样做:

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;
}

但是,如果它确实获得了新副本,则会进行不必要的初始化。或者,您可以简单地检查f之前doSomething()并在不符合预期的情况下抛出异常。

于 2010-12-12T12:22:18.023 回答
0

当您想要维护任何变量或对象的状态时使用引用(即,在被调用例程对变量/对象进行了一些处理之后,将相同的变量重新发送给调用例程)以及在将大数据传递到的情况下该功能否则将有大量数据的双重副本。

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

于 2010-12-12T12:50:01.433 回答
-1

我的正常规则是:

  1. 始终使用按值传递。

    很简单吧?参考很烂。他们不应该被介绍。

  2. 如果您有“数据结构之类的值”,请通过它。如果您有一个“类似数据结构的对象”,请传递一个指针(引用语义,按值传递)。

    通常很清楚类型是什么类型的东西:值或对象。如果你可以改变它,它就是一个对象。

于 2010-12-12T15:28:37.440 回答