我正在处理一个包含QT小部件的表单,我必须在QTextEdit字段中设置一些值。 我不得不调用一个声明为:
的函数 void SDB::setDescription(const char *Description);
当我通过这种方法调用它时(i)
const char * desc = saveOptionsDesLineEditBox->text().toStdString().c_str();
SDB::setDescription(desc);
它在窗口小部件的文本框中显示无法识别的符号。 但是通过第二种方法调用(ii)
SDB::setDescription(saveOptionsDesLineEditBox->text().toStdString().c_str());
工作正常。 为什么这两种方法有区别?
答案 0 :(得分:7)
std::string
返回的saveOptionsDesLineEditBox->text().toStdString()
是暂时的。它超出了行尾的范围,并且随着其内容被销毁。 因此,在下一行中引用由const char*
到c_str()
返回的包含的desc
是未定义的行为。
<小时/> 当你打电话给
时
SDB::setDescription(saveOptionsDesLineEditBox->text().toStdString().c_str());
所有在同一语句中,临时存在的时间足够长setDescription
可以安全地读取和复制c字符串。
我建议采用
的方式std::string desc = saveOptionsDesLineEditBox->text().toStdString();
SDB::setDescription(desc.c_str());
严格来说,这将产生一个超过必要的副本(或者如果你有c++11
则移动),但是谁真正关心这里。使代码更容易理解本身就是一件好事。
(注意,这是一个猜测,没有看到任何功能签名,但它很可能是一个很好的。)
答案 1 :(得分:3)
我猜.toStdString()返回一个std :: string,而不是一个。的std :: string&安培;对某些稳定的物体。
如果是这样,它是一个临时的,将在完整表达式的末尾被破坏(这是最后一个;在行中)。在此之前,您从该临时请求了一个const char *并存储它。只有字符串存在才有效。
你可以解决这样的情况:
const auto& desc = saveOptionsDesLineEditBox->text().toStdString();
SDB::setDescription(desc.c_str());
或者只是将整个表达式放在setDescription调用中。