将std :: string作为const引用返回

时间:2012-11-22 07:27:42

标签: c++ string reference const stdstring

我怀疑将std :: string作为const引用返回。

class sample
{
public:
  std::string mString;
  void Set(const std::string& s)
  {
    mString = s;
  }
  std::string Get()
  {
    return mString;
  }
 };

在Set函数中,我将std :: string作为const引用传递给const,因为它的值在函数内部没有变化。

而在Get功能中,实际上我在这里很困惑。返回std :: string作为值更有意义。但我不确定,通过传递字符串作为const引用有任何好处。通过回转字符串作为参考将增加exectuion速度,我想是的,但我不确定。但是把它作为'const为它做出任何好处?

4 个答案:

答案 0 :(得分:15)

决定如何从某种容器中返回一个非平凡的对象的问题实际上并不重要:

  • 如果返回值的类对对象施加任何类型的约束,则不能返回非const引用,因为它将失去强制执行其不变量的可能性。显然,如果调用成员函数的对象也不是const,那么通过非const引用返回一个对象是可行的。
  • 向对象公开const引用可以避免不变量的问题,但仍然暗示相应类型的对象实际上是作为实现细节保存在内部。
  • 按值返回对象可能会导致复制对象的成本很高。

如果你的类是一个可行的monitor,你肯定希望按值返回对象,否则在调用者有机会复制它之前可以对对象进行变异。

基本上,没有一个选择是理想的。如果有疑问,我会按值返回,除非知道对象的复制成本很高,在这种情况下我可能返回const&

答案 1 :(得分:12)

通过引用或const引用返回没有速度差异 - 两者都非常快,因为它们只返回对原始对象的引用,不涉及复制。

可以通过该引用修改(非const)引用返回的对象。在您的具体示例中,mString是公共的,因此无论如何(并且直接)都可以对其进行修改。但是,getter和setter的常用方法(及其引入的主要原因)是封装 - 您只允许通过getter / setter访问您的数据成员,以便您可以检测设置的无效值,响应值更改和通常只是将类的实现细节隐藏在其中。所以getter通常通过const引用或值返回。

但是,如果您通过const引用返回,它会将您绑定到始终在您的类中保留std::string的实例来备份引用。也就是说,即使你以后想要重新设计你的类,以便它在getter中动态计算字符串而不是在内部存储它,你也不能。您必须同时更改公共界面,这可能会破坏使用该类的代码。例如,只要您通过const-reference返回,这是完全有效的代码:

const std::string *result = &aSample.Get();

如果将Get()更改为按值而不是const引用返回,则此代码当然会生成悬空指针 不再编译(感谢Steve Jessop纠正我)

总而言之,我采取的方法是将mString设为私有。 Get()可以按值或const-reference返回,具体取决于您是否确定存储了一个字符串。该课程将如下所示:

class sample
{
  std::string mString;

public:
  void Set(const std::string &s)
  {
    mString = s;
  }
  std::string Get() const
  {
    return mString;
  }
};

答案 2 :(得分:3)

这里最常见的做法是将值作为const引用返回,然后您可以根据需要使用引用或复制值:

const std::string& Get() const
{
    return mString;
}

sample mySample;
const std::string &refString = mySample.Get(); // Const-reference to your mString
const std::string copyString = mySample.Get(); // Copy of your mString

如果你真的需要来返回字符串的副本,那么你可以避免使用“The Most Important Const”复制字符串返回值:

sample mySample;
const std::string &myString = mySample.Get();
// myString is now valid until it falls out of scope, even though it points to a "temporary" variable

答案 3 :(得分:0)

将其作为参考。如果需要副本,它当然可以从该引用中获得。