Reputation: 53
Consider this simple code:
class A {
public:
int value;
A(int value) { this->value = value; }
~A() { printf("destroying %d\n", value); }
A operator ++() { return A(value + 1); }
};
int main() {
A a(1);
printf("before increment: %d\n", a.value);
a = ++a;
printf("after increment: %d\n", a.value);
return 0;
}
This outputs:
before increment: 1
destroying 2
after increment: 2
destroying 2
Why is the value of a
1 more before being destroyed?
Upvotes: 4
Views: 160
Reputation: 1689
In operator++ method you create temporary A object which is then destroyed when you return it from the function. There should be also another copy construction and destroying, but RVO elides this one.
When you add log to constructor also you will see better what is going on. I also allowed myself to change printf to cout, for more c++ish coding style.
#include <iostream>
class A {
public:
int value;
A(int value) {
std::cout << "creating " << value << std::endl;
this->value = value;
}
~A() {
std::cout << "destroying " << value << std::endl;
}
A operator ++() { return A(value + 1); }
};
int main() {
A a(1);
std::cout << "before increment: " << a.value << std::endl;
a = ++a;
std::cout << "after increment: " << a.value << std::endl;
return 0;
}
output:
creating 1
before increment: 1
creating 2
destroying 2
after increment: 2
destroying 2
You can also read about canonical implementations of operators overloading:
http://en.cppreference.com/w/cpp/language/operators
operator++ overloading should look like this:
struct X
{
X& operator++() // prefix version
{
// actual increment takes place here
return *this;
}
X operator++(int) // postfix version
{
X tmp(*this); // copy
operator++(); // pre-increment
return tmp; // return old value
}
};
Upvotes: 4
Reputation: 5665
int main() {
A a(1); // a.value = 1;
printf("before increment: %d\n", a.value);
a = ++a; // 1. create temporary object of type A with a.value+1
// 2. copy temporary object to object a.
// 3. destroy temporary object.
printf("after increment: %d\n", a.value);
return 0;
}
Basically you can declare pre-increment operator here as constant for clarity
A operator ++() const { return A(value + 1); }
But expected behavior is:
A& operator ++() { ++value; return *this; }
Upvotes: 2
Reputation: 36463
It's pretty simple:
a = ++a;
First, a new temporary A
object is created that holds a value
of 2
(value + 1 = 2
), this object is moved/copied to a
and then destroyed (which is the first destroying 2
print you see). Now the compiler generated move/copy constructor just does a memcopy of the members, value
in this case. value
was 2
when assigned to the temp object and thus a
's value
will be 2
too. Therefore, the final two printf
's printing out 2
is nothing surprising.
Upvotes: 0