在成员变量中存储 std::to_string(x).c_str() 会产生垃圾

use*_*212 0 c++ xcode

我有一个非常简单的 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 更改为另一个数字,也会记录完全相同的内容。

πάν*_*ῥεῖ 5

在此刻

 _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_或其他前缀约定(像我一样),只需使用我的示例中所示的后缀即可_