C ++ get方法 - 按值或按引用返回

时间:2010-05-30 15:15:30

标签: c++ reference return-value return-value-optimization

我提出了一个非常简单的问题,但不幸的是我自己无法找到答案。

假设我有一些数据结构保存设置并且像设置图一样工作。 我有一个GetValue(const std::string& name)方法,它返回相应的值。

现在我想弄清楚 - 什么样的回报价值方法会更好。显而易见的意思是让我的方法像

一样
std::string GetValue(const std::string& name) const

并返回对象的副本,并依赖于RVO的性能含义。

另一个意味着制作两个方法

std::string& GetValue(...)
const std::string& GetValue(...) const

通常意味着复制代码或使用一些邪恶的常量强制转换来使用其中一个例程。

# Q

在这种情况下你会选择什么?为什么?

4 个答案:

答案 0 :(得分:6)

这取决于用法。 GetValue("foo") = "bar"应该有意义吗?在这种情况下,按值返回并不是您想要的。

答案 1 :(得分:6)

实际上我可能会使用:

std::string GetValue(const std::string& name) const;
// or
const std::string* GetValue(const std::string& name) const;

void SetValue(std::string name, std::string value);

Setter first:

  • SetValue中按值传递允许编译器进行一些无法通过const-reference传递的优化,Dave Abrahams在"Want Speed? Pass by Value."
  • 的文章中对此进行了解释。
  • 使用Setter通常会更好,因为您可以检查正在设置的值,而使用普通引用时,您无法保证调用者不会对数据执行任何愚蠢的操作。

对于吸气者:

  • 通过复制返回似乎是浪费,因为大多数时候你不会修改返回的对象(对于设置图),但是指针或引用确实意味着对象别名会活得足够长,如果你不能保证那么重点是没有实际意义:按价值回报。另外复制允许避免暴露内部细节,例如,如果您突然切换到std::wstring,因为您需要UTF-8中的某些设置......
  • 如果你需要表现,那么你准备在这个部门做一些让步。但是,引用不允许您发出缺少属性的信号(除非您有一些魔术值),而指针使其变得容易(已经为您剪掉了NULL)。

答案 2 :(得分:2)

如果你可以通过const引用返回,那么。按值返回内存管理类(如std :: string)的唯一原因是因为它是一个临时字符串。

答案 3 :(得分:1)

这是C ++的一个非常“敏感”的观点。恕我直言,这是C ++设计中最薄弱的一点。 AFAIK没有什么不错的选择,无论是外观还是表现都很好。

应该提到的一点是,RVO优化通常只能完成部分工作。没有它这样的典型表达式:

std::string txt = GetValue("...");

实际上会产生2份! 取决于编译器,但通常RVO优化只消除一个副本,但另一个仍然存在。