ostream重载是否可以成为函数成员?

时间:2012-05-31 21:48:28

标签: c++

我有一个班级Counter,我希望重载operator <<以输出Counter的数据成员。我试图让ostream重载一个成员函数:

Counter{
public:
    std::ostream& operator<<(std::ostream& outStream, const Counter& c);
private:
    int count_;
};

std::ostream& Counter::operator<<(std::ostream& outStream, const Counter& c){
    outStream << c.count_;
    return outStream;
}

但是g ++编译器总是输出相同的错误:

  

‘std::ostream& Counter::operator<<(std::ostream&, const Counter&)’必须只使用一个参数

但是,如果我将重载函数更改为该类的朋友,它就可以正常工作,如下所示:

Counter{
public:
    friend std::ostream& operator<<(std::ostream& outStream, const Counter& c);
private:
    int count_;
};

std::ostream& operator<<(std::ostream& outStream, const Counter& c){
    outStream << c.count_;
    return outStream;
}

这是否意味着流操作符重载不能是类的成员函数?

4 个答案:

答案 0 :(得分:2)

如果将ostream运算符放在类本身中,那么它将无法按预期方式工作。这将是一个成员函数意味着调用它必须这样做:c.operator<<("output")这显然不是你的意思。为了使它像你期望的那样工作,它必须在课堂之外。您可以通过将其作为朋友或将其放在类之外并使用getter(访问器)来输出数据来完成此操作。

答案 1 :(得分:2)

添加public查询方法,该方法返回count_的值,然后它不必是friend

Counter{
public:
    int count() const { return count_; }
private:
    int count_;
};

std::ostream& operator<<(std::ostream& outStream, const Counter& c){
    outStream << c.count();
    return outStream;
}

答案 2 :(得分:2)

它不一定是朋友,但不能成为会员。成员操作符仅在与左侧操作数对应的类中时才起作用。

答案 3 :(得分:0)

不幸的是,流输出操作符(&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;必须在左边使用和声明。除非他们需要访问受保护或私人成员,否则他们不需要成为您希望流式传输的班级的朋友。这意味着,如果您可以仅使用公共函数(如观察者/访问者)来实现流操作符,而无需将其声明为朋友。

在您的第一个Counter类中,您声明该类的成员函数似乎无效。在Counter类的第二个示例中,您声明运算符重载为&lt;&lt;看似有效,可以访问私人会员。在第二个例子中,函数仍然必须在类之外声明。

Wikipedia Operators in C and C++有一个很好的运算符重载列表,包括类&lt;&lt;即使它们不是很有用,也会超载。必须向后调用类重载CounterInstance << cout;,这是违反直觉的。