Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does no default constructor result in no move constructor?

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?

like image 986
Matt Clarkson Avatar asked Apr 15 '13 15:04

Matt Clarkson


1 Answers

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.

like image 65
Andy Prowl Avatar answered Oct 06 '22 23:10

Andy Prowl