What does copying an object mean? What are the copy constructor and the copy assignment operator? When do I need to declare them myself? How can I prevent my objects from being copied?
C++ treats variables of user-defined types with value semantics. This means that objects are implicitly copied in various contexts, and we should understand what "copying an object" actually means.
Let us consider a simple example:
(If you are puzzled by the
Special member functions
What does it mean to copy a
Since we declared neither the copy constructor nor the assignment operator (nor the destructor) ourselves, these are implicitly defined for us. Quote from the standard:
By default, copying an object means copying its members:
The implicitly-defined special member functions for
Memberwise copying is exactly what we want in this case:
So when should we declare those special member functions explicitly? When our class manages a resource, that is, when an object of the class is responsible for that resource. That usually means the resource is acquired in the constructor (or passed into the constructor) and released in the destructor.
Let us go back in time to pre-standard C++.
There was no such thing as
Even today, people still write classes in this style and get into trouble:
"I pushed a person into a vector and now I get crazy memory errors!"
Remember that by default, copying an object means copying its members,
but copying the
Since memberwise copying does not have the desired effect, we must define the copy constructor and the copy assignment operator explicitly to make deep copies of the character array:
Note the difference between initialization and assignment:
we must tear down the old state before assigning to
Unfortunately, this solution will fail if
This also takes care of self-assignment without an explicit check. An even more robust solution to this problem is the copy-and-swap idiom, but I will not go into the details of exception safety here. I only mentioned exceptions to make the following point: Writing classes that manage resources is hard.
Some resources cannot or should not be copied, such as file handles or mutexes.
In that case, simply declare the copy constructor and copy assignment operator as
Alternatively, you can inherit from
The rule of three
Sometimes you need to implement a class that manages a resource. (Never manage multiple resources in a single class, this will only lead to pain.) In that case, remember the rule of three:
(Unfortunately, this "rule" is not enforced by the C++ standard or any compiler I am aware of.)
Most of the time, you do not need to manage a resource yourself,
because an existing class such as
The Rule of Three is a rule of thumb for C++, basically saying
The reasons for this is that all three of them are usually used to manage a resource, and if your class manages a resource, it usually needs to manage copying as well as freeing.
If there is no good semantic for copying the resource your class manages, then consider to forbid copying by declaring (not defining) the copy constructor and assignment operator as
(Note that the forthcoming new version of the C++ standard (which is C++11) adds move semantics to C++, which will likely change the Rule of Three. However, I know too little about this to write a C++11 section about the Rule of Three.)
The law of the big three is as specified above.
An easy example, in plain English, of the kind of problem it solves:
Non default destructor
You allocated memory in your constructor and so you need to write a destructor to delete it. Otherwise you will cause a memory leak.
You might think that this is job done.
The problem will be, if a copy is made of your object, then the copy will point to the same memory as the original object.
Once, one of these deletes the memory in its destructor, the other will have a pointer to invalid memory (this is called a dangling pointer) when it tries to use it things are going to get hairy.
Therefore, you write a copy constructor so that it allocates new objects their own pieces of memory to destroy.
Assignment operator and copy constructor
You allocated memory in your constructor to a member pointer of your class. When you copy an object of this class the default assignment operator and copy constructor will copy the value of this member pointer to the new object.
This means that the new object and the old object will be pointing at the same piece of memory so when you change it in one object it will be changed for the other objerct too. If one object deletes this memory the other will carry on trying to use it - eek.
To resolve this you write your own version of the copy constructor and assignment operator. Your versions allocate separate memory to the new objects and copy across the values that the first pointer is pointing to rather than its address.
What does copying an object mean? There are a few ways you can copy objects--let's talk about the 2 kinds you're most likely referring to--deep copy and shallow copy.
Since we're in an object-oriented language (or at least are assuming so), let's say you have a piece of memory allocated. Since it's an OO-language, we can easily refer to chunks of memory we allocate because they are usually primitive variables (ints, chars, bytes) or classes we defined that are made of our own types and primitives. So let's say we have a class of Car as follows:
A deep copy is if we declare an object and then create a completely separate copy of the object...we end up with 2 objects in 2 completely sets of memory.
Now let's do something strange. Let's say car2 is either programmed wrong or purposely meant to share the actual memory that car1 is made of. (It's usually a mistake to do this and in classes is usually the blanket it's discussed under.) Pretend that anytime you ask about car2, you're really resolving a pointer to car1's memory space...that's more or less what a shallow copy is.
So regardless of what language you're writing in, be very careful about what you mean when it comes to copying objects because most of the time you want a deep copy.
What are the copy constructor and the copy assignment operator?
I have already used them above. The copy constructor is called when you type code such as
When do I need to declare them myself? If you are not writing code that is to be shared or for production in some manner, you really only need to declare them when you need them. You do need to be aware of what your program language does if you choose to use it 'by accident' and didn't make one--i.e. you get the compiler default. I rarely use copy constructors for instance, but assignment operator overrides are very common. Did you know you can override what addition, subtraction, etc. mean as well?
How can I prevent my objects from being copied? Override all of the ways you're allowed to allocate memory for your object with a private function is a reasonable start. If you really don't want people copying them, you could make it public and alert the programmer by throwing an exception and also not copying the object.
Basically if you have a destructor (not the default destructor) it means that the class that you defined has some memory allocation. Suppose that the class is used outside by some client code or by you.
If MyClass has only some primitive typed members a default assignment operator would work but if it has some pointer members and objects that do not have assignment operators the result would be unpredictable. Therefore we can say that if there is something to delete in destructor of a class, we might need a deep copy operator which means we should provide a copy constructor and assignment operator.
Rule of three in C++ is a fundamental principle of the design and the development of three requirements that if there is clear definition in one of the following member function, then the programmer should define the other two members functions together. Namely the following three member functions are indispensable: destructor, copy constructor, copy assignment operator.
Copy constructor in C++ is a special constructor. It is used to build a new object, which is the new object equivalent to a copy of an existing object.
Copy assignment operator is a special assignment operator that is usually used to specify an existing object to others of the same type of object.
There are quick examples:
Many of the existing answers already touch the copy constructor, assignment operator and destructor. However, in post C++11, the introduction of move semantic may expand this beyond 3.
Recently Michael Claisse gave a talk that touches this topic: http://channel9.msdn.com/events/CPP/C-PP-Con-2014/The-Canonical-Class
The Rule of Three states that if you declare any of a
then you should declare all three. It grew out of the observation that the need to take over the meaning of a copy operation almost always stemmed from the class performing some kind of resource management, and that almost always implied that
A consequence of the Rule of Three is that the presence of a user-declared destructor indicates that simple member wise copy is unlikely to be appropriate for the copying operations in the class. That, in turn, suggests that if a class declares a destructor, the copy operations probably shouldn’t be automatically generated, because they wouldn’t do the right thing. At the time C++98 was adopted, the significance of this line of reasoning was not fully appreciated, so in C++98, the existence of a user declared destructor had no impact on compilers’ willingness to generate copy operations. That continues to be the case in C++11, but only because restricting the conditions under which the copy operations are generated would break too much legacy code.
Declare copy constructor & copy assignment operator as private access specifier.
In C++11 onwards you can also declare copy constructor & assignment operator deleted