QString createString()
{
return QString("foobar");
}
const QString& getString()
{
return createString();
}
这将产生VS2013着名的“警告C4172:返回本地变量或临时地址”。
现在,如果我将第二种方法更改为
const QString& getString()
{
const QString& binder = createString();
return binder;
}
不再报告错误。这是一种安全的方法来修复警告而不改变API的签名吗?为什么这样做?
答案 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
超出范围后。它不再定义。
您可以通过使活页夹保持活动来定义它。