4

我正在处理具有 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());

工作正常。为什么这两种方法有区别?

4

2 回答 2

7

std::string返回的人是saveOptionsDesLineEditBox->text().toStdString()临时的。它在行尾超出范围,并连同其内容一起被销毁。因此,在下一行中引用throughconst 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),但谁真的在乎呢。使代码更易于理解本身就是一件好事。

(注意,这是一个猜测,没有看到任何函数签名,但它很可能是一个很好的。)

于 2013-05-30T12:06:22.220 回答
3

我猜 .toStdString() 返回一个 std::string,而不是一个 . std::string& 到一些稳定的对象。

如果是这样,它是一个临时的,将在完整表达式的末尾被销毁(即最后一个 ; 在该行中)。在此之前,您从该临时文件中询问了一个 const char* 并将其存储。仅在字符串存在时才有效。

您可以像这样解决这种情况:

const auto& desc = saveOptionsDesLineEditBox->text().toStdString();
SDB::setDescription(desc.c_str());

或者只是将整个表达式放在 setDescription 调用中。

于 2013-05-30T12:12:40.123 回答