正确返回对局部变量的const引用

时间:2015-06-23 15:17:31

标签: c++ qt

除了答案123GotW88之外,还假设以下方法

QString createString()
{
    return QString("foobar");
}

const QString& getString()
{
    return createString();
}

这将产生VS2013着名的“警告C4172:返回本地变量或临时地址”。

现在,如果我将第二种方法更改为

const QString& getString()
{
    const QString& binder = createString();
    return binder;
}

不再报告错误。这是一种安全的方法来修复警告而不改变API的签名吗?为什么这样做?

3 个答案:

答案 0 :(得分:7)

它不起作用。这样你就可以通过使情况更难分析来抑制警告。行为仍然未定义。

答案 1 :(得分:2)

你的"修复"没有按'吨

要保留签名,您必须做出一些权衡。至少getString不是可重入的,除了返回字符串的副本之外,它不能被修复。它也不是线程安全的,虽然可以在不改变签名的情况下修复。

至少要保留签名,您必须自己保留字符串。一个简单的解决方案可能如下所示:

const QString & getString() {
  static QString string = createString();
  return string;
}

另一种方法是使字符串成为类成员,如果你的函数真的是一个方法:

class Foo {
  QString m_getString_result;
public:
  const QString & getString() {
    m_getString_result = createString();
    return m_getString_result;
  }
};

为了线程安全,您需要将结果保存在线程本地存储中。这仍然无法解决重入问题 - 因此,鉴于您拥有的签名,它无法修复。

答案 2 :(得分:1)

此行为未定义。

const QString& getString()
    {
        const QString& binder = createString();
        return binder;
    }

binder超出范围后。它不再定义。    您可以通过使活页夹保持活动来定义它。