重载<<操作符(C ++)

时间:2019-08-29 00:23:05

标签: c++ operator-overloading

根据Can't Overload operator<< as member function

  

当作为成员函数重载时,<< <<被解释为   a.operator <<(b),因此它只需要一个显式参数(此为   一个隐藏的参数)。

     

因为这需要重载作为用作类的类的一部分   左手操作数,对于普通的ostream等无效。它   将要求您的重载成为ostream类的一部分,而不是   你班上的一部分由于您不允许修改ostream类,   你不能那样做。剩下的只是全局过载   替代。

我知道例如:

friend std::ostream& operator<< (std::ostream &out, const Obj &obj);

就像一个函数,该函数接受一个ostream对象和您要打印的某个对象,然后返回一个ostream对象。

但是我不知道cout << obj会如何调用此函数。

cout << obj不会做cout.operator<<(obj)之类的事情,这正是我们不想要的吗?那么,为什么实际上要调用该函数呢?为什么它允许返回值返回到cout

编辑:

我以前已经读过What are the basic rules and idioms for operator overloading?,它指出

  

“应用于对象x和y的二进制中缀运算符@被称为   作为operator @(x,y)或x.operator @(y).4“

这提供了一些进一步的说明,但是我看不出它如何回答我的问题。

2 个答案:

答案 0 :(得分:2)

这并不是您做的很好,就是您引用的答案。

操作员重载可以是成员,也可以是非成员。

例如,anOstream << aT可以用ostream& ostream::operator<<(T)(或类似名称)或自由函数ostream& operator<<(ostream&, T)来解析。这些都可以被调用。就是这样。这就是标准所说的。

由于我们无法在ostream中添加内容,因此后者就是我们的处理方式(尽管对于您自己的类型,这完全取决于您)。

请注意,对于这些示例,我如何选择ostream&的返回类型;这就是“返回值返回到cout”的方式:左侧操作数只是通过引用返回。

答案 1 :(得分:2)

如果存在,编译器将调用cout.operator <<(obj),但如果不存在,它将寻找兼容的全局函数。

例如在它下面将调用成员函数。但是,如果将其注释掉,它将调用全局函数。

#include <iostream>
class Ostr;

class Obj {
    public:
    void print(Ostr& os) const;
};
class Ostr {
    public:
    Ostr& operator<<(const Obj& obj){
        std::cout << "member";
        obj.print(*this);
        return *this;
    }
    Ostr& operator<<(const char* obj){
        std::cout << obj;
        return *this;
    }
};
void Obj::print(Ostr& os) const {
    os << "Obj";
}

template<class T>
auto operator<<(Ostr& os, const T& t) -> decltype(t.print(os), os) { 
    os << "global";
    t.print(os); 
    return os; 
} 

int main() {
    Obj obj;
    Ostr ostr;
    ostr << obj;
    return 0;
}