C++ is an Object-Oriented Programming (OOP) language, and OOP is a way to integrate with objects which can contain data in the form (attributes or properties of objects), and code blocks in the form of procedures (methods, 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. Classes and structs are very useful in modern developing tools. There are some rules to support the principles of programming, one of which is the Rule of Three in C++. In this post, we explain the Rule of Three in C++ with examples.
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.
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
What is the Rule of Three in C++?
If you are new to classes and don’t know about these three special member functions, here are 3 posts about: Copy Constructor, Copy Assignment Operator, and Destructor,
How can we apply the Rule of Three in C++?
Here is a simple example that follows the Rule Of Three,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
class Ta { public: Ta(Ta const& other) // copy constructor { } Ta& operator =(Ta const& other) // copy assignment operator { } ~Ta() // destructor { } }; |
Here you may have constructor, or other special or user defined members too.
Is there a full example of the Rule of Three in C++?
Here is a simple example that follows rule of three,
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 |
#include <iostream> #include <string> class Tuser { public: std::string name; int age; Tuser(const std::string& name, int age) : name(name), age(age) // Constructor { } Tuser(const Tuser& that) : name(that.name), age(that.age) // I. copy constructor { } Tuser& operator=(const Tuser& that) // II. copy assignment operator { name = that.name; age = that.age; return *this; } ~Tuser() // III. destructor { } }; int main() { Tuser user1("Yilmaz Yoru", 48); // using constructor Tuser user2(user1); // I. using copy constructor Tuser user3 = user1; // II. using assignment operator std::cout << user2.name << " (" << user2.age << ")" << std::endl; std::cout << user3.name << " (" << user3.age << ")" << std::endl; system("pause"); return 0; // III. destructor of all declarations are used } |
Is the Rule of Three outdated in C++ now?
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 which states that if you need to define any of the five special members ( copy constructor, copy assignment operator, move constructor, move assignment operator, destructor), then you probably need to define or delete (or at least consider) all five.
In other words, this the Rule of Three is only valid for the compilers before C++11.
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 }; |
As you see in modern C++ these 5 special members are automatically generated as a default for each new class.
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.