Here, I have a very simple program that moves a value from one object to another, making sure to remove the value from the one that it was taken from (leaving behind a '0').
#include <iostream>
struct S
{
S(char val) : m_val(val) {}
S& operator=(S&& other) noexcept
{
this->m_val = other.m_val;
other.m_val = '0';
return *this;
}
char m_val = '0';
};
int main()
{
S a('a');
S b('b');
std::cout << "a.m_val = '" << a.m_val << "'" << std::endl;
std::cout << "b.m_val = '" << b.m_val << "'" << std::endl;
a = std::move(b);
std::cout << "a.m_val = '" << a.m_val << "'" << std::endl;
std::cout << "b.m_val = '" << b.m_val << "'" << std::endl;
return 0;
}
As expected, the output of this program is:
a.m_val = 'a'
b.m_val = 'b'
a.m_val = 'b'
b.m_val = '0'
The value of 'b' is transferred from object b to object a, leaving a '0' behind. Now, if I generalize this a bit more with a template to (hopefully) automatically do the move and delete business, here's what I end up with... (distilled down of course).
#include <iostream>
template<typename T>
struct P
{
P<T>& operator=(P<T>&& other) noexcept
{
T& thisDerived = static_cast<T&>(*this);
T& otherDerived = static_cast<T&>(other);
thisDerived = otherDerived;
otherDerived.m_val = '0';
return *this;
}
protected:
P<T>& operator=(const P<T>& other) = default;
};
struct S : public P<S>
{
S(char val) : m_val(val) {}
char m_val = '0';
};
int main()
{
S a('a');
S b('b');
std::cout << "a.m_val = '" << a.m_val << "'" << std::endl;
std::cout << "b.m_val = '" << b.m_val << "'" << std::endl;
a = std::move(b);
std::cout << "a.m_val = '" << a.m_val << "'" << std::endl;
std::cout << "b.m_val = '" << b.m_val << "'" << std::endl;
return 0;
}
When run, the output is:
a.m_val = 'a'
b.m_val = 'b'
a.m_val = '0'
b.m_val = '0'
Uh oh! Somehow BOTH objects got "deleted". When I step through the body of the move assignment operator code... all seems well! a.m_val is 'b' like we expect... right up until the return *this; statement. Once it returns from the function, suddenly that value gets set back to '0'.
Can anybody please shed some light on why this is happening?