In the C++ programming language, Object-Oriented Programming (OOP) is a good way to represent and manipulate data and work with functions. Classes and Objects are the best way to work on properties and methods. In a professional C++ Compiler, one of the OOP features is the copy assignment operator that is used with “operator=” to create a new object from an existing one. In this post, we explain what the Deleted Implicitly-declared copy assignment operator in C++ examples.
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; |
What is deleted implicitly-declared copy assignment operator in C++?
The Copy Assignment Operator in a class is a non-template non-static member function that is declared with the “operator=“. When you create a class, struct, or union that is copy assignable (that you can copy with the = operator symbol), it has a default copy assignment operator.
The implicitly-defined copy assignment operator is defined If neither deleted nor trivial. That means this operator has a function body which is generated and compiled. This is called as implicitly-defined copy assignment operator. This operator can be deleted, then this is called a deleted implicitly-defined copy assignment operator or we say that the implicitly-defined copy assignment operator is deleted.
How does a deleted implicitly-declared copy assignment operator occur in C++?
In C++, T
represents a literal type, it can be function, class type (class
, struct
, union
object types, …), fundamentals type ( void
, bool
, char
, wchar_t
), compound types (reference
, pointer
, array, function, enumeration).
Normally, a copy assignment operator is defined as default in any new type T
definition. We can list these below for the deleted implicitly-defined copy assignment operator,
- If type
T
has a user-declared move constructor, implicitly-declared copy assignment operator for class typeT
is defined as deleted - If type
T
has a user-declared move assignment operator, an implicitly-declared copy assignment operator for class typeT
is defined as - If type
T
has a base class that has deleted copy assignment operator, implicitly-declared copy assignment operator for class typeT
is defined as deleted
A copy assignment operator is defined as default in any new type T
definition.
A copy assignment operator is defined as default in any new type T definition. If you just need default copy assignment operator, you don’t need to declare anything about it, it is automatically declared and defined. Here is a simple example below,
If type T
has a user-declared move constructor, implicitly-declared copy assignment operator for class type T
is defined as deleted
If type T
has a user-declared move constructor, implicitly-declared copy assignment operator for class type T
is defined as deleted. Let’s give an example to this. Assume that we have a class with user-defined implicitly-declared copy assignment operator which is empty (no operation) as given 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 |
#include <iostream> #include <string> class TmyclassA { public: std::string str; TmyclassA& operator=( const TmyclassA& other) // user-defined implicitly-declared copy assignment operator { } }; int main() { TmyclassA o1, o2; o1.str = "LearnCplusplus.org"; o2 = o1; // Using user-defined implicitly-declared copy assignment operator std::cout << o1.str << std::endl; std::cout << o2.str << std::endl; system("pause"); return 0; } |
If we run this example you will see that implicitly-declared copy assignment operator (which is default) is deleted and our new empty assignment operator definition is running. This is why second line is empty (Normally, you will see two text lines of “LearnCplusplus.org”)
1 2 3 4 5 |
LearnCplusplus.org Press any key to continue . . . |
If type T
has a user-declared move assignment operator, an implicitly-declared copy assignment operator for class type T
is defined as deleted
If type T
has a user-declared move assignment operator, an implicitly-declared copy assignment operator for class type T
is defined as deleted. Let’s give an example of this. Assume that we have a class with user-defined implicitly-declared copy assignment operator:
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 |
#include <iostream> #include <string> class TmyclassA { public: std::string str; int i; //Constructor TmyclassA() { }; // Move Constructor TmyclassA(TmyclassA&& obj) noexcept : str( std::move(obj.str )), i(std::exchange(obj.i, 0)) { }; }; int main() { TmyclassA o1, o2; return 0; } |
This will delete the implicitly-defined copy assignment operator. If we compile this example, we will see an error as shown below.
1 2 3 |
ERROR: object of type 'TmyclassA' cannot be assigned because its copy assignment operator is implicitly deleted |
If type T
has a base class that has deleted copy assignment operator, implicitly-declared copy assignment operator for class type T
is defined as deleted
If type T
has a base that has deleted copy assignment operator, f type T
has a deleted copy assignment operator for class type T
is defined as deleted. Let’s give an example of this. Assume that we have a TmyclassA
base class that has deleted copy assignment operator, and if we use this base class in another class TmyclassB
as below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#include <iostream> #include <string> class TmyclassA { public: TmyclassA& operator=( const TmyclassA& other) = delete; }; class TmyclassB : public TmyclassA { }; int main() { TmyclassB o1, o2; return 0; } |
if we compile this example, using copy assignment operator will give this error.
1 2 3 |
ERROR: object of type 'TmyclassA' cannot be assigned because its copy assignment operator is implicitly deleted |
What is more about deleted implicitly-defined copy assignment operator in C++?
In addition to these, a defaulted copy assignment operator for class T
is defined as deleted If type T
has one of a non-static data member of :
- A const-qualified non-class type.
- A reference type.
- A non-static data member that cannot be copy-assigned.
- A direct base class that cannot be copy-assigned.
- A variant member that has non-trivial assignment operator.
In Modern C++, as you see, we may cause to deletion of implicitly-declared copy assignment operator for class type in C++, as listed in these conditions above.
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.