const char *和literal string之间有什么区别?

时间:2013-05-30 11:59:48

标签: c++ qt

我正在处理一个包含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());

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

2 个答案:

答案 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调用中。