如果将其定义operator<<
为成员函数,则与使用non-member相比,它将具有不同的分解语法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
,这里链中的第二个参数的位置如何。...奇怪吗?