我有一个重载<<我的reckful类的运算符实现如下:
ostream& operator << (ostream& os, const reckful& p)
{
os << p.PrintStuff();
return os;
}
PrintStuff()只是reckful的成员函数,返回一个字符串。
我理解事物的方式,如果我在main()中写cout << reckobject << endl;
之类的东西,cout << reckobject
将优先,我的重载&lt;&lt; (使用cout作为左操作数,reckobject作为右操作数)将返回ostream对象os
,留下要评估的表达式os << endl;
,它将输出字符串然后结束该行。所以,第一个&lt;&lt;是我宣布的那个,第二个是标准&lt;&lt;正确?
然而,我的主要问题是......事件的顺序是什么,它是左右操作数,以及&lt;&lt;当我运行这样的语句时,运算符就是这样的:
cout << "reckful object = " << reckobject << "!" << endl;
如果没有一个ostream对象和一个&lt;&lt;&lt;&lt;&lt;&lt; ?
感谢。
答案 0 :(得分:5)
如果你注意到实现<<
的标准方法,它会返回ostream本身。这是关键部分
类似
cout << "reckful object = " << reckobject << "!" << endl;
将调用
一次
cout << "reckful object = "
此函数调用将返回ostream
,用于进行第二次调用
即
cout << reckobject;
等等等等。
您可以通过实施<<
void operator << (ostream& os, const reckful& p)
{
os << 1;
}
在这种情况下你可以做到
std::cout << p;
但不是
std::cout << p << std::endl;
运算符使其更难理解,但请考虑此Point
类
struct Point
{
Point& setX( int x) { X = x; return *this;}
Point& setY( int y) { Y = y; return *this;}
int X;
int Y;
};
setX
和setY
的定义方式允许
Point p;
p.setX( 2 ).setY( 4 );
这与<<
用于链接函数调用的机制相同。
答案 1 :(得分:3)
因为每个<<
都会返回对cout
的引用。因为运算符<<
是左关联的,所以调用是从左到右完成的,所以
a << b << c
相当于
(a << b) << c
等于 1 到
operator<<(operator<<(a, b), c);
所以在你的例子中,你正在做
operator<<(operator<<(operator<<(operator<<(cout, "reckful object = "), reckobject), "!"), endl);
正如您所看到的,每个<<
取决于之前<<
的返回值(如果没有进一步左cout
,则仅<<
)。如果您将<<
的某个返回类型更改为void
,则会有效停止<<
次调用,因为void
不能用作参数一个功能。
1 它并不完全等价,因为在那个例子中,所有operator<<
都是自由函数,而实际上,有些可以是成员函数,所以你可以混合使用成员和非成员函数 - 成员呼叫
operator<<(a, b).operator<<(c);
或
operator<<(a.operator<<(b), c);