我正在尝试制作一个Console类。我想在课程中包含cin
和cout
并重载<<
和>>
运算符。所以我可以这样使用这个类:
// Output
Console << "Call cout from Console" << endl;
// Input
string str;
Console >> str; // Call cin
我最好的猜测是:
class Console {
//...
public:
ostream& operator<< (ostream& os)
{
cout << os;
return &cout;
}
//...
};
但我知道这是错的,我如何重置运营商以将Console类用作cin
和cout
?
答案 0 :(得分:2)
我不知道为什么要做这样的事情,但它不是你需要捕获的流而是另一种类型。但如果这只是为了使std :: cout和std :: cin更方便我不会打扰。
class console {
};
template<typename T>
console& operator<<(console con, const T& val) {
std::cout << val;
return con;
}
console c;
c << "hello world\n";
答案 1 :(得分:2)
这不是你问题的直接答案,但也许我指出了一些替代方案。
请参阅我的answer其他问题。要自己定义所有这些<<
和>>
运算符并不容易。但是,您可以覆盖控制台的streambuf。使用cin和cout的组合streambufs,
从std::iostream
和std::streambuf
class console_streambuf : public std::streambuf {
public:
console_streambuf() {
// no buffering, overflow on every char
setp(0, 0);
}
virtual int_type overflow(int_type c) {
std::cout << c;
return c;
}
...
};
class console : public std::iostream {
public:
console() { rdbuf(&buf); }
private:
console_streambuf buf;
};
答案 2 :(得分:1)
与上面的许多答案相反,使用模板的魔力,做你想做的事情非常简单。
我建议使用字符串流,因为使用ostream(cout是ostream)可能需要神秘的黑魔法(不是玩笑)。
#include <string>
#include <iostream>
#include <sstream>
struct console {
std::stringstream data_;
console() : data_() { };
// We make ourselves a template sink so we can "take" operator<<'s.
// The awesome advantage to using a template like this is that the
// compiler will allow us to "take" any data that can be converted
// to a stringstream, which will handle converting int's etc.
// for us!
template<typename T>
console& operator<<(const T& what) {
data_ << what;
return *this; // We must return a reference if we want to
// string together more than one thing, i.e.
// b << " " << 4;
}
void flush() {
std::cout << data_.str();
data_.clear();
std::cout.flush();
}
};
int main()
{
int a = 4;
console b;
console c;
b.data_ << 2;
c.data_ << 4;
//b << std::cout; // WHAT? it's possible but stupid, prints garbage
// Because we made the template return a reference, this will
// allow us to chain things just like we do with cout.
b << " HELLO WORLD! " << "yo!" << 4;
b << a << " " << 4.2f;
// Compiler chokes on this. It will try to convert "console"
// to a stringstream which it can't.
//b << c;
b.flush(); // Send out the output
// Wait for key press
char foo[500];
gets(foo);
}
输出:
2 HELLO WORLD! yo!44 4.2
就像cout一样,当然除了更多的控制权。 如果你想要二进制I / O,你可以使用basic_ostream和basic_istreams,但除非你真的需要它,否则我建议不要使用它。
答案 3 :(得分:-1)
必须使用左侧和右侧要调用的特定类型声明重载的运算符函数。因此,您需要operator<< (int)
,operator<< (double)
,operator<< (const std::string &)
等
如果您真的要将它们传递给cin和cout,您可以使用模板成员函数来保存输入,例如:
template <class T> Console& operator<< (const T& x) { cout << x; return *this; }
[感谢André指出它应该返回Console&amp;所以你可以将Console << a << b;
]