If a class doesn't have a default constructor as it should always initialize it's internal variables, would it follow that it shouldn't have a move constructor?
class Example final {
public:
explicit Example(const std::string& string) : string_(
string.empty() ? throw std::invalid_argument("string is empty") : string) {}
Example(const Example& other) : string_(other.string_) {}
private:
Example() = delete;
Example(Example&& other) = delete;
Example& operator=(const Example& rhs) = delete;
Example& operator=(Example&& rhs) = delete;
const std::string string_;
};
This class always expects the internal string to be set by a non-empty string and the internal string is copied between Example
objects. Am I correct that a move constructor does not apply here because if an Example was moved it would have to leave the string empty via a std::move
call?
If a class doesn't have a default constructor as it should always initialize it's internal variables, would it follow that it shouldn't have a move constructor?
No, I wouldn't say so.
The fact of moving from an Example
object and leaving it with an empty string should not be a problem here, because usually a client should not make any assumption on the state of a moved-from object, apart from the fact that it is legal.
This means, that clients can only invoke functions that have no pre-conditions on the state of their Example
input. Notice, that normally almost all of the member functions of Example
would have pre-conditions on the state of the object (i.e. string_
must be a non-null string), but not exactly all of them.
For instance, the destructor of Example
should not mind if string_
is empty - why wouldn't it be allowed to do its job even in that case? The assignment operator is another common example - why would it not be allowed to assign a new string to string_
?.
Under this view, leaving an Example
object with an empty string is OK, because all that clients can do with a moved-from object is basically either re-assigning it or destroying it - and for these use cases, it should not matter whether string_
is empty.
Therefore, having a move constructor and a move assignment operator does make sense.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With