I'm asking something that looks trivial but I had problems with. Let's assume, for the sake of explanation, a structure like this one:
class MyClass{
int* m_Number;
public:
int value() const {return *m_Number;}
void setValue(int val){*m_Number=val;}
MyClass() : m_Number(new int(3)){}
~MyClass() {if(m_Number) delete m_Number;}
MyClass(const MyClass& other):m_Number(new int(*other.m_Number)){}
MyClass& operator=(const MyClass& other){if(m_Number) *m_Number=*other.m_Number; else m_Number=new int(*other.m_Number); return *this;}
MyClass& operator=(MyClass&& other){std::swap(m_Number,other.m_Number); return *this;}
MyClass(MyClass&& other){
//????
}
}
What should I put in there? My options are:
1)
MyClass(MyClass&& other)
:m_Number(other.m_Number)
{
other.m_Number=nullptr;
}
But then the moved from object is not in a valid state. calling value() should return something valid but undetermined while here I just segfault. I could check m_Number in value() and setValue() but you realise it's a huge drag in real code.
2)
MyClass(MyClass&& other)
:m_Number(other.m_Number)
{
other.m_Number= new int(3);
}
But a move constructor that can throw is a no go (or at least as I understand it) and it's also a drag of the performance enhancement, in fact this code is equal or worse that the copy constructor.
What do you think?
Did I miss something?
Is there a preferred way to go?
Thanks in advance
Edit: This question received an answer from the convener of the std committee and it fundamentally disagrees with the answers to this post. You can find it in this article https://herbsutter.com/2020/02/17/move-simply/