Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Default move constructor in a sub class

In C++11, if the base class has defined its own move (copy) constructor (assignment operator), does its subclass need to define its own move (copy) constructor (assignment operator) in where call the base class's corresponding constructor/operator is called explicitly?

Is it a good idea to define the constructor, destructor, move/copy constructor (assignment operator) clearly every time?

struct Base {
    Base() {}
    Base(Base&& o);
};

struct Sub : public Base {
    Sub(Sub&& o) ;  // Need I do it explicitly ? If not,what the compiler will do for me
};
like image 522
hl1020 Avatar asked Sep 04 '14 11:09

hl1020


People also ask

What does the default move constructor do?

A move constructor enables the resources owned by an rvalue object to be moved into an lvalue without copying. For more information about move semantics, see Rvalue Reference Declarator: &&.

Does compiler provide default move constructor?

In C++, the compiler creates a default constructor if we don't define our own constructor. In C++, compiler created default constructor has an empty body, i.e., it doesn't assign default values to data members. However, in Java default constructors assign default values.

What does std :: move () do?

std::move is used to indicate that an object t may be "moved from", i.e. allowing the efficient transfer of resources from t to another object. In particular, std::move produces an xvalue expression that identifies its argument t . It is exactly equivalent to a static_cast to an rvalue reference type.

Why should move constructor be Noexcept?

noexcept is nice for two reasons: The compiler can optimize a little better because it doesn't need to emit any code for unwinding a call stack in case of an exception, and. It leads to incredible performance differences at runtime for std::vector (and other containers, too)


2 Answers

The compiler will generate a default move constructor if you don't specify one in the base class (except some cases, e.g. there's a base class with a deleted move constructor) but you should, in any case, call explicitly the base class' one if you have it:

Sub(Sub&& o) : Base(std::move(o))
like image 126
Marco A. Avatar answered Sep 22 '22 14:09

Marco A.


According to the standard (N3797) 12.8/9 Copying and moving class objects [class.copy]:

If the definition of a class X does not explicitly declare a move constructor, one will be implicitly declared as defaulted if and only if

— X does not have a user-declared copy constructor,

— X does not have a user-declared copy assignment operator,

— X does not have a user-declared move assignment operator, and

— X does not have a user-declared destructor.

As such, if your class meets the above requirements then a default move constructor will be implicitly declared for you.

As already being stated, the base-class has no knowledge of any sub-classes. As such, whether you declare a move constructor in one base class has no effect on the implicit generation of a move constructor in its sub-classes.

As far as it concerns whether you should declare explicitly a constructor/destructor etc. of a class, there's this nice article.

like image 36
101010 Avatar answered Sep 24 '22 14:09

101010