stringstream的第一个字符串参数保存为指针/垃圾

Pri*_*tic 4 c++ pointers stringstream memory-address

可能重复:
在C++中将字符串打印到临时流对象
std :: ostringstream打印c-string的地址而不是其内容

我正在尝试使用stringstream构建一个字符串,就像你使用cout一样.这适用于类似日志记录的类.我遇到的问题是,如果<<运算符的第一个参数是一个字符串,当我随后使用stringstream :: str()调用打印出该字符串流时,我得到一个垃圾地址,而不是字符串.这只发生在FIRST字符串中.后续字符串很好.数字总是好的.这是代码:

    // class I use to print out the stream
    class StreamWriter
    {
    public:
        StreamWriter()
        {}

        ~StreamWriter()
        {
            std::string myMessage = m_stringstream.str();
            std::cout << myMessage << std::endl;
        }

        std::stringstream m_stringstream;
    };

    // macro for simplification
    #define OSRDEBUG (StreamWriter().m_stringstream)

    // actual use
    OSRDEBUG << "Hello " << "my " << "name is Pris " << 123456;

    // output
    0x8054480my name is Pris 123456
    0x8054480my name is Pris 123456
    0x8054480my name is Pris 123456
    0x8054480my name is Pris 123456
Run Code Online (Sandbox Code Playgroud)

任何人都可以了解正在发生的事情,以及我如何解决这个问题?

编辑:以下更改(除了padiablo的示例)也适用,维护类的析构函数与宏的使用.

    // class I use to print out the stream
    class StreamWriter
    {
    public:
        StreamWriter()
        {   m_stringstream = new std::stringstream;   }

        ~StreamWriter()
        {
            std::string myMessage = m_stringstream.str();
            std::cout << myMessage << std::endl;
            delete m_stringstream;
        }

        std::stringstream * m_stringstream;
    };

    // macro for simplication
    #define OSRDEBUG *(StreamWriter().m_stringstream)
Run Code Online (Sandbox Code Playgroud)

最初的问题仍然存在,因为它看起来应该可行......而且我认为知道什么时候将它变成生产质量的代码可能很重要.

Xeo*_*Xeo 5

问题确实是流是临时的.

在C++ 11之前,没有非成员operator<<重载将rvalue引用作为第一个参数(也就是说,允许写入临时流).

因此,唯一有效的operator<<重载是成员,因为所有非成员重载都采用非const引用,因此不会绑定到临时值.其中一个非成员重载是负责打印C字符串(aka char const*)的重载.这是成员重载之一:

basic_ostream<Ch, Traits>& operator<<(void* p);
Run Code Online (Sandbox Code Playgroud)

并猜猜你的字符串文字可以自由转换为什么.:)

在第一个字符串之后,您将从调用中获得正常的引用operator<<,这将允许非成员重载可行.