重载<<运算符的函数调用 (C++)

Function call for overloaded << operator (C++)

本文关键字:lt C++ 运算符 重载 函数调用      更新时间:2023-10-16

根据不能重载运算符<<作为成员函数

当重载为成员函数时,<<b 被解释为 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

编辑:

我已经阅读了运算符重载的基本规则和习语是什么? 以前和它指出

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

这提供了一些进一步的清晰度,但我看不出它如何回答我的问题。

这正是你引用的答案所说的,尽管它做得不是很好。

运算符重载可以是成员,也可以是非成员。

例如,可以使用ostream& ostream::operator<<(T)(或类似(或自由函数ostream& operator<<(ostream&, T)来解决anOstream << aT。可以调用其中任何一个。事情就是这样。这就是标准所说的。

由于我们无法向ostream添加内容,因此后者就是我们的工作方式(尽管,对于您自己的类型,这几乎取决于您(。

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

如果 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;
}