我有一个非常简单的 C++ 程序:
using namespace std;
class TheClass
{
private:
const char *_numberString;
public:
TheClass(int number)
{
_numberString = to_string(number).c_str();
}
operator const char *()
{
return _numberString;
}
};
int main(int argc, const char * argv[])
{
TheClass instance = 123;
cout << (const char *)instance << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我在 Xcode 中运行它时,它会记录\367\277_\377. 如果我把它改成这样:
using namespace std;
class TheClass
{
public: // Change 1/2
const char *_numberString;
public:
TheClass(int number)
{
_numberString = to_string(number).c_str();
}
operator const char *()
{
return _numberString;
}
};
int main(int argc, const char * argv[])
{
TheClass instance = 123;
instance._numberString = to_string(123).c_str(); // Change 2/2
cout << (const char *)instance << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它按应有的方式记录123。我看不出我做错了什么。即使我将 123 更改为另一个数字,也会记录完全相同的内容。
在此刻
_numberString = to_string(number).c_str();
Run Code Online (Sandbox Code Playgroud)
您正在存储一个指向临时值的内部数据的指针std::string,该指针在该行代码之后无效。
有效访问_numberString调用未定义的行为。
正如评论中提到的,没有必要将_numberString1成员保留为const char*。使用std::string成员代替:
class TheClass {
private:
std::string numberString_;
public:
TheClass(int number) : numberString_(to_string(number)) {
}
operator const std::string& () {
return numberString_;
}
};
Run Code Online (Sandbox Code Playgroud)
1)您不应该_对类成员名称使用前缀,这是为编译器和标准实现内在函数保留的。如果您不喜欢类似的模式m_或其他前缀约定(像我一样),只需使用我的示例中所示的后缀即可_。