我试图用自定义流运算符实现一个类,并从它继承,以便拥有一个基类和一个具有不同流的派生类。然后我重载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;
}
我做错了什么以及如何打印预期的输出?
答案 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.
}