无法成功返回我通过在字符串上调用c_str()创建的const char*.(C++)

Cap*_*Tid 0 c++ string scope return lifetime

我的程序中有一个类,它有一个成员变量,一个名为number的int,以及一个成员函数getName(),它是MEANT,它将单词"Dice:#"作为const char*返回,但是#替换了按类中存储的数字.

const char* getName(){
 return "Dice:";
}
Run Code Online (Sandbox Code Playgroud)

效果很好.

const char* getName(){
 std::stringstream ss;
 ss << number;
 std::string s;
 s = "Dice: " + ss.str();
 return s.c_str();
}
Run Code Online (Sandbox Code Playgroud)

不能正常工作,并返回似乎是垃圾的东西.我无法弄清楚正确的方法.如果我使用cout打印s.c_str()它打印我期望的.

Sam*_*hik 5

简短而甜蜜的回答是,你不能这样做,就像你设置它一样.

std::string从中检索您的对象c_str()位于函数的本地范围内.当函数返回时,该std::string对象被销毁.

std::string s;
Run Code Online (Sandbox Code Playgroud)

是一个本地函数对象.当函数返回时,它不再存在.它加入了合唱团隐形.它不复存在了.这是一个前对象.

当一个std::string对象被破坏时,它c_str()的任何一个都不再有效.这就是你得到垃圾的原因:未定义的行为.

如果不以某种方式改变它的整体设计,就无法做到这一点.有很多方法可以继续.一些可能性:

返回一个std::string摆在首位

刚刚返回std::stringgetName().无论谁调用它都可以存储std::string一段时间,并c_str()在需要时抓住它.

使用std::string不同范围的

如果这getName()是一个类方法,你可以拥有一个私有std::string类成员,getName()将字符串存储在那里,然后返回它c_str().

由于原始版本std::string仍然存在,因此返回的内容c_str()仍然有效.请注意,这里有一些陷阱.如果呼叫者getName()再次呼叫,则先前返回的c_str()将不再有效.

结论

养成std::string在C++代码中使用和使用s 的习惯.这就是他们的目的.

名称"c_str()"应该是一个线索.如果在附近有任何C代码,它会为你提供一个与C代码一起使用的字符串.这是一个C字符串.你在这里写C代码吗?不,你正在编写C++代码.

除非你正在编写C代码,或者正在与C库交谈,否则首先不需要使用c_str().如果您正在编写C++代码,那么您应该使用std::strings.如果需要调用C库函数,请调用c_str()以传递相应的C库函数参数,并且不再说这个C字符串.