In C++, constructors are one of the important parts of class types. There are different constructor types in C++ classes and the Copy Constructor is one of these. Copy Constructors are not only used in classes but also used with struct and union data types. In this post, we will try to explain the types of Copy Constructors in modern C++.
Table of Contents
What is the Constructor in C++ classes?
The Constructor in C++ is a function, a method in the class, but it is a ‘special method’ that is automatically called when an object of a class is created. We don’t need to call this function. Whenever a new object of a class is created, the Constructor allows the class to initialize member variables or allocate storage. This is why the name Constructor is given to this special method. Here is a simple constructor class example below.
1 2 3 4 5 6 7 8 9 10 |
class myclass { public: myclass() { std::cout << "myclass is constructed!\n"; }; }; |
What is Copy Constructor in C++?
The Copy Constructor in classes (i.e class_name
) is a non-template constructor whose first parameter is class_name&
, const class_name&
, volatile class_name&
, or const volatile class_name&
. It can be used with no other parameters or with the rest of the parameters all have default values.
The Copy Constructor is a constructor type for classes that class_name must name the current class, or it should be a qualified class name when it is declared at namespace scope or in a friend declaration.
What are the types of Copy Constructors in C++ ?
Now let’s see different types of copy constructors in usage. First, let’s learn deceleration of a copy constructor.
1. Typical Declaration of a Copy Constructor
Syntax to declare Copy Constructor,
1 2 3 |
class_name (const class_name &) |
Syntax to use Copy Constructor, this copy source_class to new_class as below,
1 2 3 |
class_name new_class(source_class); |
An example with a 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 |
#include <iostream> class myclass { public: int param; myclass() // Default Constructor { }; myclass(const myclass& a) // Copy Constructor { param = a.param; // we need to copy values of each properties as in here }; }; int main() { myclass class1; class1.param=100; std::cout << class1.param << '\n' ; // Copy Class1 to Class2 by using Copy Constructor myclass class2(class1); std::cout << class2.param << '\n' ; getchar(); return 0; } |
and the output will be,
1 2 3 4 |
100 4358220 |
Here are more details and a full example about this feature.
2. Forced Copy Constructor (Default Copy Constructor)
In C++, we can force a copy constructor of a class to be generated by the compiler.
Syntax,
1 2 3 |
class_name ( const class_name & ) = default; |
An example with a 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 |
class myclass { public: int param; myclass() // Default Constructor { }; myclass(const myclass& ) = default; // Copy Constructor with atrributes as default }; int main() { myclass class1; class1.param=100; myclass class2(class1); std::cout << class1.param << '\n' ; std::cout << class2.param << '\n' ; getchar(); return 0; } |
Now, this is same as example before and copy constructor copies not only class properties and methods but also copies values of current class without and definition by user. This method is very useful to copy all parameters in one time. Result will be as follows,
1 2 3 4 |
100 100 |
Here are more details and a full example about this feature,
3. Avoiding Implicit Generation of the Copy Constructor (Deleted Copy Constructor)
Deleted Copy Constructor is used if you are Avoiding implicit generation of the copy constructor.
Syntax,
1 2 3 |
class_name ( const class_name & ) = delete; |
In example, copy constructor can be defined with attributes as delete;
1 2 3 4 5 6 7 8 9 10 11 |
class myclass { public: myclass() // Default Constructor { }; myclass(const myclass& ) = delete; // Copy Constructor with attributes as delete }; |
Here are more details and a full example about this feature,
4. Implicitly-Declared Copy Constructor
In C++, the compiler declares a Copy Constructor as a non-explicit inline public member of its class If a copy constructor is not defined for a class type (struct, class, or union), We can Implicitly declare a copy constructor when defining a new class. Remember that copy constructor has this syntax,
1 2 3 4 5 6 |
class_name (const class_name& ) // Copy Constructor { }; |
and this Copy Constructor will be declared implicitly when declaring a new class as below,
1 2 3 4 5 6 |
class new_class_name : access_type class_name { // Copy Constructor will be Declared Implicitly }; |
Here is an example,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
class myclass { public: myclass() // Default Constructor { }; myclass(const myclass& ) // Copy Constructor { }; }; class my_otherclass : public myclass // Implicitly-Declared Copy Constructor { }; |
Here are more details and a full example about this feature,
5. Implicitly-Defined Copy Constructor
The implicitly-defined copy constructor is defined by the compiler if Implicitly Declared Copy Constructor is not deleted. In union types this implicitly-defined copy constructor copies the object representation by using std::memmove statement. In other non-union class types (like classes and structs), their constructor performs full member-wise copy of the object’s bases and non-static members, in their initialization order, using direct initialization. Remember that copy constructor has this syntax,
1 2 3 4 5 6 |
class_name (const class_name& ) // Copy Constructor { }; |
and this Copy Constructor will be defined implicitly when declaring a new class as below,
1 2 3 4 5 6 |
class new_class_name : access_type class_name { new_class_name() : clas_name() { } // Copy Constructor Defined Implicitly }; |
The generation of the implicitly-defined copy constructor is deprecated if T has a user-defined destructor or user-defined copy assignment operator.
Here are more details and full example about this feature.
6. Deleted Implicitly-Declared Copy Constructor
In C++, we can implicitly declare a copy constructor while it is deleted in previous class. The implicitly-declared or defaulted copy constructor for a class is defined as deleted if,
- class has non-static data members that cannot be copied
- class has direct or virtual base class that cannot be copied
- class has direct or virtual base class with a deleted or inaccessible destructor
- class is a union-like class and has a variant member with non-trivial copy constructor
- class has a data member of rvalue reference type;
- class has a user-defined copy constructor or copy assignment operator
The compiler declares a Copy Constructor as a non-explicit inline public member of its class If a copy constructor is not defined for a class type (struct, class, or union), We can Implicitly declare a copy constructor when defining a new class.
Remember that copy constructor has this syntax,
1 2 3 4 5 6 |
class_name (const class_name& ) // Copy Constructor { }; |
and this Copy Constructor will be declared implicitly when declaring a new class as below,
1 2 3 4 5 6 |
class new_class_name : access_type class_name { // Copy Constructor will be Declared Implicitly }; |
If we combine both with a Deleted copy Constructor, here is an Deleted Implicitly-Declared Copy Constructor example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
class myclass { public: myclass() // Default Constructor { }; myclass(const myclass& ) = delete; // Copy Constructor Deleted }; class my_otherclass : public myclass { my_otherclass(const myclass& a) : myclass() // Deleted Implicitly-Declared Copy Constructor { }; }; |
Here are more details and a full example about this feature,
7. Trivial Copy Constructor
A Trivial Copy Constructor for a non-union class effectively copies all properties (scalar sub objects, all sub objects of sub objects) of the argument and performs no other action. However, padding bytes need not be copied, and even the object representations of the copied sub objects need not be the same as long as their values are identical. In general, the syntax to declare Copy Constructor is the following:
1 2 3 |
class_name (const class_name &) |
If you don’t declare anything as above, the class has a Copy Constructor, and a new subclass may have this Copy Constructor which is called a Trivial Copy Constructor. Syntax to use Copy Constructor which copies source_class
to new_class
as below,
1 2 3 |
class_name new_class(source_class); |
The copy constructor for a class is trivial if all below is maintained,
- The class is not user-provided
- The class has no virtual member functions
- The class has no virtual base classes
and also note that,
- The copy constructor selected for every direct base of the class is trivial
- The copy constructor selected for every non-static class type (or array of class type) member of the class is trivial
Here are more details and a full example about this feature,
8. Eligible Copy Constructor
Since C++11, a copy constructor is defined as eligible if it is not deleted.
Since C++20, a copy constructor is eligible if
- Copy Constructor is not deleted, and
- Copy Constructor associated constraints, if any, are satisfied,
- no copy constructor with the same first parameter type is more constrained than it
The triviality of eligible copy constructors determines whether the class is an implicit-lifetime type and whether the class is a trivially copyable type.
1 2 3 4 5 6 7 8 9 10 |
class myclass { public: myclass(const myclass&) // Eligible Copy Constructor { }; }; |
Here are more details and a full example about this feature,
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