Do compilers (let us use g++ as the specific example) provide a default move constructor and default move assignment operator when we write a class?
Compilers provide a default:
Will a compiler provide a default move constructor or move assignment operator.
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.
In general, the compiler should generate move members if you have no user-declared copy members nor destructor. = default and = delete counts as user-declared. If you declare one move member (e.g. move constructor), the other will not be implicitly generated. The compiler will never implicitly delete move members.
The move assignment operator is different than a move constructor because a move assignment operator is called on an existing object, while a move constructor is called on an object created by the operation. Thereafter, the other object's data is no longer valid.
Yes, default operator= is a shallow copy. By the way, the actual difference between shallow copy and deep copy becomes visible when the class has pointers as member fields.
Move Constructors and Move Assignment Operators (C++) This topic describes how to write a move constructor and a move assignment operator for a C++ class. 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: &&.
To create a move assignment operator for a C++ class Define an empty assignment operator that takes an rvalue reference to the class type as its parameter and returns a reference to the class type, as demonstrated in the following example: MemoryBlock& operator=(MemoryBlock&& other) { }
The compiler also creates a copy constructor if we don’t write our own copy constructor. Unlike the default constructor, the body of the copy constructor created by the compiler is not empty, it copies all data members of the passed object to the object which is being created.
Copy constructors are used to initialize a class by making a copy of an object of the same class. Copy assignment is used to copy one class object to another existing class object. By default, C++ will provide a copy constructor and copy assignment operator if one is not explicitly provided.
According to cppreference:
Implicitly-declared move constructor
If no user-defined move constructors are provided for a class type (struct, class, or union), and all of the following is true:
- there are no user-declared copy constructors
- there are no user-declared copy assignment operators
- there are no user-declared move assignment operators
- there are no user-declared destructors (until C++14) the implicitly-declared move constructor is not defined as deleted due to conditions detailed in the next section
then the compiler will declare a move constructor as a non-explicit inline public member of its class with the signature T::T(T&&).
A class can have multiple move constructors, e.g. both T::T(const T&&) and T::T(T&&). If some user-defined move constructors are present, the user may still force the generation of the implicitly declared move constructor with the keyword default.
And according to cppreference:
Implicitly-declared move assignment operator
If no user-defined move assignment operators are provided for a class type (struct, class, or union), and all of the following is true:
- there are no user-declared copy constructors
- there are no user-declared move constructors
- there are no user-declared copy assignment operators
- there are no user-declared destructors (until C++14) the implicitly-declared move assignment operator would not be defined as deleted
then the compiler will declare a move assignment operator as an inline public member of its class with the signature T& T::operator=(T&&).
A class can have multiple move assignment operators, e.g. both T& T::operator=(const T&&) and T& T::operator=(T&&). If some user-defined move assignment operators are present, the user may still force the generation of the implicitly declared move assignment operator with the keyword default.
Because some assignment operator (move or copy) is always declared for any class, the base class assignment operator is always hidden. If a using-declaration is used to bring in the assignment operator from the base class, and its argument type could be the same as the argument type of the implicit assignment operator of the derived class, the using-declaration is also hidden by the implicit declaration.
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