如何重载<<运营商?

时间:2009-07-15 01:02:41

标签: c++ visual-c++ operators operator-overloading operator-keyword

我打算在调用m_logger<<"hello"<<"world"时调用函数。 m_logger属于ofstream类型。

所以我决定重载&lt;&lt;以下签名

friend ofstream& operator<<(ofstream &stream,char *str);

然而,vc编译器会出现以下错误:

  

错误C2666:'operator&lt;&lt;' :6次重载有类似的转换

有没有其他方法可以实现这一点,我的目标是将所有写操作转移到ofstream对象到不同的函数?

创建我自己的calss对象对我有用,但是我怎样才能使它像普通的ofstream对象一样工作,它将所有系统定义的类型强制转换为字符串或char *。我知道一种方法是为每种类型的运算符重载但是有一种更清洁的方法

5 个答案:

答案 0 :(得分:5)

“过载”不是“覆盖”。您可以为不同类型的参数重载函数或运算符;你不能用你自己的实现覆盖现有的函数或操作符(除了覆盖虚函数,这显然是非常不同的)。唯一的例外是operator newoperator delete,其中可以覆盖内置的。

答案 1 :(得分:2)

您可以更改m_logger对象的类型。

答案 2 :(得分:2)

根据您想要重载运算符&lt;&lt;的原因,正确的解决方案是

  • 使用除ostream后代之外的其他类型作为目标流;在这种情况下,你必须写所有运算符&lt;&lt;你自己,但如果你想默认转发,你可以从模板中获得帮助。

像这样:

template <typename T>
myStream& operator<<(myStream& s, T const& v)
{
    s.getStream() << v;
}

你会发现操纵者与模板不匹配,所以你还需要这样的东西:

myStream& operator<<(myStream& fl, std::ostream& (*fn)(std::ostream&))
{
    s.getStream() << fn;
}
  • 编写自己的streambuf,它将I / O委托给std :: filebuf(这有点太复杂了,不能在这里给出一个例子,搜索网页 - 过滤streambuf是一个很好的关键词。如果我没记错的话,boost有一个可能有用的辅助库。请注意,在这种情况下,你最终可能会使用另一种类型的fstream,但它会从ostream下载。

答案 3 :(得分:2)

问题是ofstream已经以这种方式重载了。如果您使用mlogger的新类型ofstream,则可以执行此操作:

class mlogger_t {
public:
    ofstream stream;
    ...
}

mlogger_t& operator<<(mlogger_t& stream, const string& str) {
    stream.stream << str;
    ...
}

//EDIT: here is how to make this work for other types too using templates:
template<typename T> mlogger_t& operator<<(mlogger_t& stream, T val) {
    stream.stream << val;
}

...

mlogger_t mlogger;

mlogger << "foo";

另外,你绝对应该使用const string&(就像我在本例中所做的那样)而不是C风格的字符串。如果真的需要它是C风格,至少使用const char *

答案 4 :(得分:1)

你应该做的是做一个课,然后定义operator<<。运算符重载必须至少包含一个用户定义的类型。同样,您无法编写新的operator+(int, int)