The Move Constructor is one of the great features of Object Oriented Programming in C++, such as other features like; copy assignment operator constructors, copy constructors, move assignment operators, destructors, etc. Since the C++11 standards, in modern development, the move constructor allows you to move the resources from one object to another object without copying them. One of the move constructors is the Implicitly-defined Move Constructor which is defined or defaulted in a base class, and in this post, we explain What is Implicitly-defined Move Constructor in Modern C++.
First, let’s remember what are the classes and objects in C++.
Table of Contents
What are classes and objects in modern C++?
Classes are defined in C++ using the keyword class
followed by the name of the class. Classes are the blueprint for the objects. They are user-defined data types that we can use in our program, and they work as an object constructor. Objects are an instantiation of a class. In C++ programming, most of the commands are associated with classes and objects, along with their attributes and methods. Here is a simple class example below.
1 2 3 4 5 6 7 |
class Tmyclass { public: std::string str; }; |
Then we can create our objects with this Type of myclass as below.
1 2 3 |
Tmyclass o1, o2; |
Now, lets see what is move constructor,
What is a move constructor in modern C++?
The move constructor is a constructor that allows you to move the resources from one object to another object without copying them. In other words, the move constructor allows you to move the resources from an rvalue
object into an lvalue
object.
The move constructor is used to move data of one object to the new one, it effectively makes a new pointer to the members of an old object and transfers the resources to the heap memory. When you move a member, if the data member is a pointer, you should also set the value of the member of the old object to a NULL value. When you use the move constructor, you don’t use unnecessary data copying in the memory. This allows you to create objects faster. Mostly, if your class/object has a move constructor, you can use other move methods of other features of C++, for example, std::vector
, std::array
, std::map
, etc. For example, you can create a vector with your class type then you can use the push_back()
method that runs your move constructor.
Here is the most common syntax for the move constructor in C++ (since C++11).
1 2 3 |
class_name ( class_name && ) |
This general syntax is also a syntax for the “Typical declaration of a move constructor” as shown below.
1 2 3 4 5 |
class_name ( class_name && ) // Declaration { // Definition } // Definition |
What is an implicitly-defined move constructor in modern C++?
The Implicitly-defined Move Constructor is a Move Constructor which is implicitly defined by another base, or it is an implicitly-declared move constructor neither deleted nor trivial.
- The Implicitly-defined Move Constructor is defined, which means it has a function body with { } that is generated and compiled by the compiler implicitly.
- The implicitly-defined move constructor performs full move operations on its members if it is a class or struct type.
- The implicitly-defined move constructor copies the object representation (as in std::memmove) if it is a union type.
According to this paper by Bjarne Stroustrup,
- By default, an aggregate of elements has an implicitly defined move constructor if every element has a move constructor.
- An implicitly defined move constructor for an aggregate of elements is explicit if any of its elements have their move constructor explicit. Similarly for a copy constructor
and in addition to these above,
- From C++11 to C++20, the implicitly-defined move constructor is constexpr if it satisfies the requirements of a constexpr constructor.
- Since C++23, the implicitly-defined move constructor is constexpr if it satisfies the requirements of a constructor function.
Is there a simple example of an implicitly-defined move constructor in modern C++?
In modern C++ example, this simple class example has a move constructor as default.
1 2 3 4 5 6 7 8 |
class Tx { public: std::string str = "LearnCPlusPlus.org"; }; |
This is same like as below.
1 2 3 4 5 6 7 8 9 10 11 12 |
class Tx { public: std::string str = "LearnCPlusPlus.org"; Tx() = default; // Constructor Tx(Tx&& other) = default; // Move Constructor }; |
We can define our own move constructor as shown here:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class Tx { public: std::string str = "LearnCPlusPlus.org"; Tx() = default; // Constructor Tx(Tx&& other) // Move Constructor Declaration { // Move Constructor Definition str = std::move(other.str); // Move Constructor Definition } // Move Constructor Definition }; |
And, we can use this Tx class as base class to define a new Ty
class as below.
1 2 3 4 5 6 7 8 9 |
class Ty : public class Tx // uses Tx as a base class { public: void print_str(){ std::cout << str << std::endl; } // This class has Implicitly-defined Move Constructor from Tx class }; |
As you see, this new Ty
class above has Implicitly-defined move constructor from Tx
class. Because it is implicitly defined, not deleted and not trivial.
Is there a full example of an implicitly defined move constructor in modern C++?
Here is a full example that uses implicitly defined move constructor from a base class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
#include <iostream> #include <string> class Tx { public: std::string str = "LearnCPlusPlus.org"; Tx() = default; // Constructor Tx(Tx&& other) // Move Constructor Declaration { // Move Constructor Definition str = std::move(other.str); // Move Constructor Definition } // Move Constructor Definition }; class Ty : public Tx // uses Tx as a base class { public: void print_str(){ std::cout << str << std::endl; } // This class has Implicitly-defined move constructor from Tx class }; int main() { class Ty o1; class Ty o2 = std::move(o1); // using Implicitly-defined move constructor from Tx o1.print_str(); o2.print_str(); system("pause"); return 0; } |
Here is another full example of an implicitly defined move constructor with a template class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
#include <iostream> #include <string> class Tx { public: std::string str = "LearnCPlusPlus.org"; Tx() = default; // Constructor Tx(Tx&& other) // Move Constructor Declaration { // Move Constructor Definition str = std::move(other.str); // Move Constructor Definition } // Move Constructor Definition }; template <class T> class myclass { public: T myT; void print_str(){ std::cout << myT.str << std::endl; } // This template has Implicitly-defined move constructor from class T }; int main() { myclass<Tx> t1; myclass<Tx> t2 = std::move(t1); // using Implicitly-defined move constructor from template t1.print_str(); t2.print_str(); system("pause"); return 0; } |
If you need more technical details about the move constructor, it is explained by Bjarne Stroustrup and Lawrence Crowlcan in this publication here; https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3053.html
C++ Builder is the easiest and fastest C and C++ IDE for building simple or professional applications on the Windows, MacOS, iOS & Android operating systems. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for cross-platform UIs.
There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from here. For professional developers, there are Professional, Architect, or Enterprise version.
Design. Code. Compile. Deploy.
Start Free Trial
Free C++Builder Community Edition