In C++, classes and structs are one of the most important parts of modern app development. In modern C++, there are some rules to support the principles of programming, one of which is the Rule of Five in C++ (also known as the Rule of Six, including constructor). In this post, we explain What is the Rule of Five in C++ with examples.
C++ is an Object-Oriented Programming (OOP) language. OOP is a way to integrate with objects which can contain data in the form of attributes or properties of objects, and code blocks in the form of procedures such as methods and functions of objects. Most developers find that using OOP techniques help them to map real-world behavior and bring an organizational structure to data. These attributes and methods are variables and functions that belong to the class – part of the class’s code and they are generally referred to as class members.
First, let’s refresh our memory about the fact that Resource Acquisition Is Initialization (RAII) in OOP programming, and the Single Responsibility Principle and how that relates to the Rule of Zero in C++.
Table of Contents
What is resource acquisition in C++?
The principle of Resource Acquisition Is Initialization (RAII) term used in several OOP programming languages, which relates to the ability to manage resources, such as memory, through the copy and move constructors, destruction, and assignment operators. RAII is about the declaration and use of destructors, copy-move operators, and memory management in these members and methods. These cause new rules in development.
What is the single responsibility principle in C++?
The Single Responsibility Principle (SRP) is a computer programming principle that states “A module should be responsible to one, and only one, actor.” This principle exposes a rule for the classes in C++, called Rule of Zero. Now, let’s see what the Rule of Zero in C++ is.
What is the rule of zero in C++?
The Rule of Zero means that, if all members have default member functions, no further work is needed. This is the simplest and cleanest semantics of programming. The compiler provides default implementations for all of the default member functions if there are no special member functions that are user-defined. You should prefer the case where no special member functions need to be defined.
Here is more about Rule of Zero with C++ Examples,
What is the rule of three in C++?
The Rule of Three states that if you need to define a class that has any of the following special member functions a copy constructor, copy assignment operator, or destructor then usually you need to define all these three special member functions. So, these 3 special member functions below should be defined if you have at least one of them defined,
- Copy constructor
- Copy assignment operator
- Destructor
Here is more about Rule of Three with C++ examples.
What is the rule of five in C++?
The Rule of Three is outdated after C++11. C++11 comes with two additional special members of move semantics: the move constructor and the move assignment operator. So, there is another rule, the Rule of Five.
The Rule of Five states that if you need to define any of the five special members below,
- copy constructor,
- copy assignment operator,
- move constructor,
- move assignment operator,
- or a destructor
then you probably need to define or delete (or at least consider) all five of them.
Actually, this could be called “The Rule of Six“, because the default constructor should be also declared if there is a move constructor, in the Rule of Five it is excluded because it is a special member. Thus, you can add the constructor to this list.
If you have a compiler that is C++11 or over then if you need to define any of the five (or six) special members as in examples below.
Is there a simple example of the rule of five in C++?
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 16 17 |
class Tx { public: Tx() = default; // 0. constructor Tx(Tx const& other) = default; // 1. copy constructor Tx(Tx&& other) = default; // 2. move constructor Tx& operator=(Tx const& other) = default; // 3. copy assignment operator Tx& operator=(Tx&& other) = default; // 4. move assignment operator ~Tx() = default; // 5. destructor }; |
Is there an example of the rule of five with defined members in C++?
As you see in modern C++ these 5 special members are automatically generated as a default for each new class. If you need to define one of them, you should define all of these members as in this example below.
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 |
class Tx { public: std::string str; Tx() // 0. constructor { } Tx(Tx const& other) // 1. copy constructor { } Tx(Tx&& other) // 2. move constructor { } Tx& operator=(Tx const& other) //3. copy assignment operator { } Tx& operator=(Tx&& other) // 4. move assignment operator { } ~Tx() // 5. destructor { } }; |
Is there a full example of how to use the rule of five in C++?
Here is a full example about the rule of five in modern C++, you can see how you can use each of them in the main part.
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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
#include <iostream> #include <string> class Tx { public: std::string str; Tx() // 0. constructor { } Tx(Tx const& other) // 1. copy constructor { } Tx(Tx&& other) // 2. move constructor { } Tx& operator=(Tx const& other) //3. copy assignment operator { } Tx& operator=(Tx&& other) // 4. move assignment operator { } ~Tx() // 5. destructor { } }; int main() { Tx o1; // 0. Using Constructor o1.str = "LearnCplusplus.org"; Tx o2(o1); // 1. Using Copy Constructor Tx o3 = std::move(o1); // 2. Using Move Constructor o2 = o1; // 3. Using Copy Assignment Operator o3 = std::move(o2); // 4. Using Move Assignment Operator return 0; // 5. Using Destructor } |
As you see in modern C++ these 5 special members are automatically generated as a default in simple class, if you need to define one of them you should define all of them.
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