链接 operator<< 和 operator++ 的问题
Problem with chaining operator<< and operator++
我正在学习 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
好像流是反着读的,你能帮帮我吗?
让我们检查一下行
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);
这是整行。
在这样的表达式中,不能保证 operator<<(cout, obj)
会在 ++obj
之前执行。看起来在您的平台中,++obj
在 operator<<(cout, obj)
执行之前执行。这解释了这种行为。
请注意,标准已更改。如果您能够使用 C++17,您将获得预期的行为。
对于初学者来说,如果使用默认构造函数,则可以取消初始化数据成员。
要么声明数据成员像
int 变量 = 0;
或者重新定义默认构造函数,例如使用委托构造函数。
class test
{
public:
test() : test( 0 ){};
test(int i):var{i}{};
// ...
预递增运算符应该是这样的
test& operator++(){++var; return *this;}
^^^^^
在 post 递增运算符中,不使用标识符 dummy
。所以删除它
test operator++( int ){test tmp =*this;var++;return tmp;}
这条语句
cout << obj <<' '<< ++obj<<endl;
具有未定义的行为,因为读写对象 obj
未排序。
您必须将此语句拆分为两个语句
cout << obj <<' ';
cout << ++obj<<endl;
我正在学习 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
好像流是反着读的,你能帮帮我吗?
让我们检查一下行
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);
这是整行。
在这样的表达式中,不能保证 operator<<(cout, obj)
会在 ++obj
之前执行。看起来在您的平台中,++obj
在 operator<<(cout, obj)
执行之前执行。这解释了这种行为。
请注意,标准已更改。如果您能够使用 C++17,您将获得预期的行为。
对于初学者来说,如果使用默认构造函数,则可以取消初始化数据成员。
要么声明数据成员像
int 变量 = 0;
或者重新定义默认构造函数,例如使用委托构造函数。
class test
{
public:
test() : test( 0 ){};
test(int i):var{i}{};
// ...
预递增运算符应该是这样的
test& operator++(){++var; return *this;}
^^^^^
在 post 递增运算符中,不使用标识符 dummy
。所以删除它
test operator++( int ){test tmp =*this;var++;return tmp;}
这条语句
cout << obj <<' '<< ++obj<<endl;
具有未定义的行为,因为读写对象 obj
未排序。
您必须将此语句拆分为两个语句
cout << obj <<' ';
cout << ++obj<<endl;