Since the C++11 standards, one of the features of modern C++ is the move constructor that allows you to move the resources from one object to another object without copying them. One of the move constructors is forcing a move constructor to be generated by the compiler, and in this post, we explain Forced (Default) Move Constructor in Modern C++. Using a modern C++ IDE, helps you remember the features of the various C++ standards such as the move constructor and helps you catch errors before your programs reach the hands of your users.
Table of Contents
What are classes and objects in C++?
Classes are defined in C++ using keyword class
followed by the name of the class. Classes are the blueprint for the objects and 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 terms, the move constructor allows you to move the resources from an rvalue
object into to an lvalue
object.
The move constructor is used to move data of one object to the new one, it is a kind of to make 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 syntax for the default move constructor in C++ (Since C++11).
1 2 3 |
class_name ( class_name && ) = default; |
What is a default (forced) move constructor in C++?
The default (forced) move constructor is a move constructor deceleration method that has forced by = default
option. This default
option is forcing a move constructor to be generated by the compiler, here is how you can do forcing move constructor in a class.
1 2 3 4 5 6 7 8 9 10 11 12 |
class Tx { public: std::string str; Tx() = default; // Default Constructor Tx(Tx&& other) = default; // Default (Forced) Move Constructor }; |
As given here above, if you have a move constructor, you should define a Constructor too, otherwise you will have “No matching constructor for initialization of class
” error in compilation.
In modern C++, a simple class as below has all five special members (copy constructor, copy assignment, move constructor, move assignment, destructor)
1 2 3 4 5 6 |
class Tx { }; |
and this class has default move constructor as give above. If you have any of the 5 special members, you should define five of them ((Rule of Five) including move constructor too. Note that, the move constructor as in simple class here is the default move constructor.
Is there a simple example of a default (forced) move constructor in C++?
Here is a simple example of a default (forced) move constructor.
1 2 3 4 5 6 7 8 9 10 11 12 |
class Tx { public: std::string str; Tx() = default; // Constructor Tx(Tx&& other) = default; // Default (Forced) Move Constructor }; |
We can use move constructor with std::move
as in example below,
1 2 3 4 |
class Tx o1; class Tx o2 = std::move(o1); // Using Move Constructor with std::move |
Is there a full example of a default (forced) move constructor in C++?
Here is a full example of a default (forced) move constructor, where one object is moved to another one.
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 |
#include <iostream> #include <string> class Tx { public: std::string str; Tx() = default; // Constructor Tx(Tx&& other) = default; // Default (Forced) Move Constructor }; int main() { class Tx o1; o1.str = "LearnCPlusPlus.org"; class Tx o2 = std::move(o1); // Using Move Constructor std::cout << o2.str << std::endl; std::cout << o1.str << std::endl; system("pause"); return 0; } |
The outputs of str
of o2
and o1
will be as follows.
1 2 3 4 5 |
LearnCPlusPlus.org Press any key to continue . . . |
Why should I follow a rule of five in C++ if there is a move constructor?
In C++, The Rule of Five states that if a type ever needs one of the following special members, then it must have all of the five special members.
- Copy constructor
- Copy assignment
- Move constructor
- Move assignment
- Destructor
In another words, if you have move constructor in a class, you should carefully define all of them in accordance with your data members (properties).
Note that, a simple empty C++ class is perfectly equivalent to default implementations (Rule of Five) in a class. A modern compiler is able to provide all these special member functions (default implementations). In example, this simple class below.
1 2 3 4 5 6 |
class Tx { }; |
is exactly the same as the one below in modern C++.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class Tx { public: Tx() = default; // constructor Tx(Tx const& other) = default; // copy constructor Tx& operator=(Tx const& other) = default; // copy assignment operator Tx(Tx&& other) = default; // move constructor Tx& operator=(Tx&& other) = default; // move assignment operator ~Tx() = default; // destructor }; |
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
As you see in modern C++ these 5 special members are automatically generated as a default for each new class. If you have a special member of one of these you must define all of them as in Rule of Five.
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.