我正在学习C++,我遇到了这个问题:
#include <iostream>
using namespace std;
class test
{
public:
test(){};
test(int i):var{i}{};
test& operator++(){++var; return this;}
test operator++(int dummy){test tmp =*this;var++;return tmp;}
friend ostream& operator<<(ostream&, const test&);
private:
int var;
};
ostream& operator<<(ostream& o, const test& obj)
{
o<<obj.var;
return o;
}
int main()
{
test obj{2};
cout << obj << endl;
obj++;
cout << obj << endl;
cout << obj <<' '<< ++obj<<endl;
return 0;
}我期望的输出是:2 3 3 4
相反,我有:2 3 4 4
如果我将最后一个增量++obj替换为obj++,情况会更加奇怪:2 3 4 3
这就像是以相反的方式读取流,你能帮我吗?
发布于 2019-09-11 01:36:15
让我们来看看这条线是如何
cout << obj << ' ' << ++obj << endl;是被翻译的。
第1步。
cout << obj变成了
// A non-member function.
operator<<(cout, obj)第2步。
operator<<(cout, obj) << ' '变成了
// Also a non-member function.
operator<<(operator<<(cout, obj), ' ')第3步。
operator<<(operator<<(cout, obj), ' ') << ++obj变成了
// Also a non-member function.
operator<<(operator<<(operator<<(cout, obj), ' '), ++obj)第4步。
operator<<(operator<<(operator<<(cout, obj), ' '), ++obj) << endl;变成了
// A member function.
operator<<(operator<<(operator<<(cout, obj), ' '), ++obj).operator<<(endl);这就是整条线。
在这样的表达式中,不能保证在++obj之前执行operator<<(cout, obj)。在您的平台中,似乎在执行operator<<(cout, obj)之前先执行++obj。这就解释了这种行为。
请注意,标准已更改。如果您能够使用C++17,您将获得预期的行为。
发布于 2019-09-11 01:38:54
对于初学者,如果将使用默认构造函数,则可以取消初始化数据成员i。
可以像这样声明数据成员
int var = 0;
或者重新定义默认构造函数,例如使用委托构造函数。
class test
{
public:
test() : test( 0 ){};
test(int i):var{i}{};
// ...预增值运算符应该如下所示
test& operator++(){++var; return *this;}
^^^^^在后增量运算符中,不使用标识符dummy。所以把它去掉
test operator++( int ){test tmp =*this;var++;return tmp;}这句话
cout << obj <<' '<< ++obj<<endl;具有未定义的行为,因为读写对象obj是没有顺序的。
您必须将此语句拆分为两个语句
cout << obj <<' ';
cout << ++obj<<endl;https://stackoverflow.com/questions/57875745
复制相似问题