自定义ostream只打印`<<<`链的最后一个字符串

时间:2016-07-13 07:09:02

标签: c++ ofstream ostream

我试图用自定义流运算符实现一个类,并从它继承,以便拥有一个基类和一个具有不同流的派生类。然后我重载ostream运算符以使用存储的#include <string> #include <memory> #include <ostream> #include <iostream># #include <fstream> class Sink { public: Sink() { m_stream = std::unique_ptr<std::ostream>(new std::ostream(std::cout.rdbuf())); }; template<typename T> std::ostream& operator<<(const T& obj) { return *m_stream; } protected: std::unique_ptr<std::ostream> m_stream; }; class FileSink : public Sink { public: FileSink() { m_stream = std::unique_ptr<std::ostream>(new std::ofstream("file.txt")); } }; int main() { Sink s; FileSink fs; s << "First console string " << "second console string"; fs << "First file string " << "second file string"; return 0; }

这是代码的工作示例:

Sink class

我在控制台上写FileSink,文件上有second console string

问题在于,使用此代码,我只打印每条指令的最后一个字符串。

在控制台中,我看到以下输出:

second file string

在文件中我可以看到这个输出:

.grid {
    -moz-column-width: 200px;
    -webkit-column-width: 200px;
    column-width: 200px;
    -moz-column-gap: 0;
    -webkit-column-gap: 0;
    column-gap: 0;
    -webkit-perspective: 1
}

.grid .grid-block {
    display: inline-block;
    width: 100%;
}

.grid .grid-block .tiles {
    width: 100%;
    border: 1px solid red;
}

我做错了什么以及如何打印预期的输出?

2 个答案:

答案 0 :(得分:3)

您的operator<<不执行任何操作并返回std::ostream&。然后,您将std::ostream::operator<<应用于std::ostream&。期待的事情!

做你想做的事的标准方法:

template<typename T>
Sink & Sink::operator<<(const T& obj) {
    *m_stream << obj;
    return *this;
}
template<typename T>
FileSink & FileSink::operator<<(const T& obj) {
    *m_stream << obj;
    return *this;
}

为防止代码重复,您可以使用继承。我认为它可能会复制std::stream继承方案。 :)

答案 1 :(得分:2)

template<typename T>
std::ostream& operator<<(const T& obj) {
    *m_stream << obj;    // you missed this
    return *m_stream;
}

此外,您可以定义operator&lt;&lt;作为非会员职能。

template <typename T> 
Sink& operator<<(Sink &sink, const T &obj) {
    *(sink.m_stream) << obj;
    return sink;
}

并使其成为Sink的朋友:

class Sink {
    template <typename T>
    friend Sink& operator<<(Sink &sink, const T &obj);
    // other code.
}