按价值返回与按引用返回?

时间:2018-02-19 13:03:57

标签: c++ optimization

我希望通过 const引用值(出于性能原因)。

详细说明:

#include "BigDataStruct.h"

class DataGiver
{
  public:
    BigDataStruct getByValue() const { return myData; };
    const BigDataStruct& getByConstRef() const { return myData; };

  private:
    BigDataStruct myData;
}

我的直觉是, getByConstRef() 可能会(或可能不会)在 getByValue() 上的性能略有提升,例如: const BigDataStruct& someData = someDataGiver.getByConstRef(); / p>

BigDataStruct someData = someDataGiver.getByConstRef();

但是对于像以下这样的电话来说,几乎没有(几乎没有)。

z+<>

另外 - 这给了我一些不适 - 是在第一个场景中 someData someDataGiver 中的实际成员相关联,在某种意义上,如果那里的成员发生了变化< em> someData 也会发生变化,如果 someDataGiver 过期/死亡 someData 变为......未定义?

因此我试图阻止我的同事通过const引用返回(除非我们实际上因其他原因想要引用该对象 - 例如在单身工厂中)。我在这里有一点意见,还是我只是挑剔和烦扰我的同事没有充分的理由?

(我知道优化的经验法则:1)不要这样做2)不要这样做 - 并在实际操作之前使用分析器

2 个答案:

答案 0 :(得分:2)

由于它是一个反馈请求,这是我的2美分。 我想关注两个方面: 性能 安全性

性能

通过引用返回通过删除额外复制来提高性能。改进量很大程度上取决于用法:对象有多大,循环有多紧,等等。

要引入一些数据:这里是benchmark on-line(注意:BigDataStruct持有char[256]): enter image description here

  • 通过引用返回有影响。您可以根据具体情况决定它是否具有重要意义。

  • 执行BigDataStruct someData = someDataGiver.getByConstRef();时的表现是相同的

安全

通过引用返回 不是内存安全 不是线程安全的 ,因为它提供了别名可能在其他地方修改的数据(BigDataStruct)(例如,在DataGiver中)。

用一个例子说明它:

const BigDataStruct& someData = someDataGiver.getByConstRef();
// do something with someData
someDataGiver.modifyData(); //<= someData is now changed!
// doing same things with someData can have different outcome

你可能会想:没有理智的开发人员会写这样的东西。但这是一个经常发生的事情(发生在我身上):

const BigDataStruct& someData = 
    DataGiver().getByConstRef(); // Bam! A wild dangling reference appears!

结论

通过引用返回可以提高性能。但它几乎没有开发人员需要跟踪的令人讨厌的陷阱。无论是否劝阻,都是强烈建议。国际海事组织违反按价值返还并激励通过参考返回可能是一种平衡的方法。同时明确声明该值是通过引用返回的是一个好主意(您的团队已使用ByConstRef postfix执行此操作)。

更新,如评论中提到的@LightnessRacesinOrbit(另请参阅answer by Pavlo K):如果您无法控制所有getter用法(例如,开发库)或通过引用返回通过将选择权委托给最终用户来提供更大的灵活性。

答案 1 :(得分:1)

IMO这是c ++返回引用的自然方式,让сlass的用户决定如何处理它。

例如,stl容器通常通过引用返回元素,并且由开发人员根据需要将其复制到局部变量,或者通过引用使用(如果开发人员完全控制元素的生命周期)。 (以std :: vector为例)。

所以,如果没有其他原因(比如使DataGiver线程安全等),我会返回const ref。