如果您定义operator<<
为成员函数,它将具有与使用非成员不同的分解语法operator<<
。非成员operator<<
是二元运算符,其中成员operator<<
是一元运算符。
// Declarations
struct MyObj;
std::ostream& operator<<(std::ostream& os, const MyObj& myObj);
struct MyObj
{
// This is a member unary-operator, hence one argument
MyObj& operator<<(std::ostream& os) { os << *this; return *this; }
int value = 8;
};
// This is a non-member binary-operator, 2 arguments
std::ostream& operator<<(std::ostream& os, const MyObj& myObj)
{
return os << myObj.value;
}
所以....你怎么称呼他们?运算符在某些方面很奇怪,我会挑战你operator<<(...)
在头脑中编写语法以使事情有意义。
MyObj mo;
// Calling the unary operator
mo << std::cout;
// which decomposes to...
mo.operator<<(std::cout);
或者您可以尝试调用非成员二元运算符:
MyObj mo;
// Calling the binary operator
std::cout << mo;
// which decomposes to...
operator<<(std::cout, mo);
当你把这些运算符变成成员函数时,你没有义务让它们表现得直观,如果你愿意,你可以定义operator<<(int)
左移一些成员变量,理解人们可能有点措手不及,不管你有多少评论写。
几乎最后,有时操作员呼叫的两种分解都有效,您可能会在这里遇到麻烦,我们将推迟该对话。
最后,请注意编写一个看起来像二元运算符的一元成员运算符可能是多么奇怪(因为您可以使成员运算符虚拟......也试图不下放并沿着这条路径运行...... )
struct MyObj
{
// Note that we now return the ostream
std::ostream& operator<<(std::ostream& os) { os << *this; return os; }
int value = 8;
};
这种语法现在会激怒许多编码人员......
MyObj mo;
mo << std::cout << "Words words words";
// this decomposes to...
mo.operator<<(std::cout) << "Words words words";
// ... or even further ...
operator<<(mo.operator<<(std::cout), "Words words words");
请注意cout
这里链中的第二个参数是如何......奇怪的吧?