I'm learning C++ and I have this problem:
#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;
}
the output i expected was: 2 3 3 4
instead i have: 2 3 4 4
if i replace the last increment ++obj with obj++ the situation is even more weird: 2 3 4 3
it's like the stream is read in the opposite way, can you help me?
Let's examine how the line
is translated.
Step 1.
becomes
Step 2.
becomes
Step 3.
becomes
Step 4.
becomes
That's the entire line.
In such an expression there is no guarantee that
operator<<(cout, obj)
will be executed before++obj
. It appears that in your platform,++obj
is executed beforeoperator<<(cout, obj)
is executed. That explains the behavior.Please note that the standard has changed. If you are able to use C++17, you will get the expected behavior.
For starters the data member i can be uninitialized if the default constructor will be used.
Either declare the data member like
int var = 0;
Or redefine the default constructor for example by using the delegating constructor.
The pre-increment operator should look like
In the post-increment operator the identifier
dummy
is not used. So remove itThis statement
has undefined behavior because reading writing the object
obj
are not sequenced.You have to split this statement into two statements