我刚刚开始学习基本的C ++语法,我对我遇到的一段代码感到有些困惑。
对于一个名为MyString的类,有一个运算符重载定义为:
ostream& operator<<(ostream& os, const MyString& s)
{
os << s.data;
return os;
}
然后在一些驱动函数中声明:
cout << s3 << endl;
运行,其中s3是对象类型MyString。结果打印出s3的值。
我不太明白这个陈述是如何起作用的。在搞乱之后,似乎只需要调用一次复制构造函数,然后解构3个对象。这条线的确如何运作?看起来操作符接受对ostream和MyString的引用,但是它既不是endl也不是endl?另外,当有两个“&lt;&lt;”的实例时,为什么只有1个拷贝构造函数被调用?用过的?也许我甚至没有问正确的问题,或者我的问题甚至没有意义,因为我对这些问题的发生感到非常困惑。如果是这样的话,有人可以就一般情况的解释进行阐述吗?
答案 0 :(得分:7)
这是一个非常笼统的问题,但我会尽力消除你的误解。
当您说ostream& operator<<(ostream& os, const MyString& s) { ... }
时,您只是定义一个函数,该函数将ostream&
作为第一个参数,const Mystring&
作为第二个参数,并返回{{1} }。该函数恰好名为ostream&
,可以通过简写语法operator<<
调用,以调用x << y
。
执行operator<<(x, y)
时,与执行cout << s3 << endl;
相同。
从此代码中调用operator<<(operator<<(cout, s3), endl);
的复制构造函数和析构函数。您看到的消息来自其他地方。
答案 1 :(得分:1)
你可以稍微分解一下:
cout // this is the ostream your inserting to (stdout)
<< s3 // this calls your defined operator that writes s.data
<< endl; // this calls the operator<< for std::endl
ostream& operator<<(ostream& os, const MyString& s)
{
// here os is the ostream (stdout) you're using via cout
// s is s3 that you passed in
os << s.data; // this calls operator<< for data
return os; // this returns the reference so the subsequent call to << endl can append to the stream
}
答案 2 :(得分:0)
调用此语句不需要MyString复制构造函数,因为MyString作为对自定义运算符的引用传递&lt;&lt;对于MyString。
将endl not 发送给自定义运算符&lt;&lt;对于MyString。
答案 3 :(得分:0)
我猜你的编译器可以为 cout 生成复制构造函数。流是一个相当复杂的对象,但c ++的选择是提供这样的语法糖(如内联构造函数)来抽象一些细节。其他答案已经指出了使用引用的基本要点,没有为参数传递执行复制。
答案 4 :(得分:0)
语言规则表明,如果非成员函数(运算符&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&#;那个电话(正如其中一位受访者所解释的那样)我这里不使用标准术语,如果有人对此原则有更准确的描述,请告诉我们。