且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何确定输出流链是否结束?

更新时间:2022-04-20 21:20:39

您可以将有趣的逻辑放入流的析构函数中.显然,我也会正确地处理流而不是制作一些看起来像流但实际上不是流的东西:

You could put the interesting logic into the stream's destructor. Obviously, I would also properly deal with stream rather than cooking up something which somewhat looks like a stream but isn't really a stream:

#include <iostream>
#include <sstream>
#include <string>

class logstream
    : private virtual std::stringbuf
    , public std::ostream {
    std::string level;
public:
    logstream(std::string l)
        : std::ostream(this)
        , level(l) {
    }
    logstream(logstream&& other)
    : std::stringbuf(std::move(other))
    , std::ostream(std::move(other))
    , level(std::move(other.level)) {
        this->rdbuf(0);
    }
    ~logstream() {
        std::cout << "do something interesting here("
                  << this->level<< ", " << this->str() << ")
";
    }
};

logstream trace() {
    return logstream("trace");
}

int main()
{
    trace() << "hello, world";
}

使用的流缓冲区(在本例中为std::stringbuf,但也可以是自定义流缓冲区)被创建为基类,以便在 std::ostream 之前构造它代码>.原则上它是一个数据成员,但数据成员是在基类之后构造的.因此,它变成了一个 private 基类.

The stream buffer used (std::stringbuf in this case but it could also be a custom stream buffer) is made a base class to have it constructed before the std::ostream. In principle it is meant to be a data member but data members are constructed after the base classes. Thus, it is made a private base class instead.

事实证明 std::ostream 有一个 virtual 基类 (std::ios),这会导致 std::ostream 仍然在 std::stringbuf 之前构造,如果用于 std::stringbuf 的正常继承.使用 virtual 继承并使 std::stringbuf 成为第一个基类,确保它确实首先被构造.

It turns out that std::ostream has a virtual base class (std::ios) which would cause the std::ostream to still be constructed before the std::stringbuf if normal inheritance where used for std::stringbuf. Using virtual inheritance and making the std::stringbuf the first base class makes sure it really is constructed first.