我对某些情况下是否选择值或引用语义没有感觉(我希望)。我可以申请任何经验法则吗?
我通常选择除内置数据类型(char,int,bool,double等)以外的所有内容的引用。但是,有时候无法从函数返回引用,所以我必须使用指针。以下函数就是一个例子:
Foo bar()
{
Foo f;
f.do_stuff();
return f;
}
我使用boost :: shared_ptr存储Foo对象,但它使得对象非常难看。我目前正在寻找一个能够返回一个几乎不会超过10个元素的deque的函数(这就是我所假设的,我无法确定)。按价值返还可以吗?我的考虑是否是过早优化的情况?
答案 0 :(得分:3)
在任何情况下,不要通过引用或指针返回在堆栈上分配的任何内容(即本地变量,例如f)。
答案 1 :(得分:3)
按值返回很好,因为大多数编译器会优化额外的副本(这称为返回值优化,或者更确切地说是命名返回值优化)。
但惯用法是
void bar(Foo& out)
{
out.do_stuff();
}
答案 2 :(得分: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()
,如果不符合预期则抛出异常。
答案 3 :(得分:0)
当你想要维护任何变量或对象的状态时使用引用(即在被调用的例程对变量/对象进行了一些处理之后将相同的变量重新运行到调用例程),并且在传递的情况下也是如此对于函数的大数据,将会有大量数据的双重副本。
此外,在某些需要防止对象复制的情况下,在这种情况下,我们将类的复制构造函数设置为私有。
答案 4 :(得分:-1)
我的正常规则是:
始终使用按值传递。
简单,嗯?参考吮吸。它们永远不应该被引入。
如果你有一个"值,比如数据结构"交上来。如果你有像数据结构那样的对象"传递指针(引用语义,按值传递)。
通常清楚类型是什么类型的东西:价值或对象。如果你可以改变它,它就是一个对象。