Say I've got a class where the sole data member is something like std::string
or std::vector
. Do I need to provide a Copy Constructor, Destructor and Assignment Operator?
9 Answers
In case your class contains only vector/string objects as its data members, you don't need to implement these. The C++ STL classes (like vector, string) have their own copy ctor, overloaded assignment operator and destructor.
But in case if your class allocates memory dynamically in the constructor then a naive shallow copy will lead to trouble. In that case you'll have to implement copy ctor, overloaded assignment operator and destructor.

- 445,704
- 82
- 492
- 529
The usual rule of thumb says: if you need one of them, then you need them all.
Not all classes need them, though. If you class holds no resources (memory, most notably), you'll be fine without them. For example, a class with a single string
or vector
constituent doesn't really need them - unless you need some special copying behavior (the default will just copy over the members).

- 263,248
- 89
- 350
- 412
-
Instead of saying, "not all classes need them," wouldn't it be more accurate to say "retaining the default copy constructor, destructor and assignment operator will be fine."? (That is, you won't need to override the defaults with your own implementations.) – DavidRR Feb 06 '13 at 14:37
The default copy constructor will copy the vector if it is declared by value. Beware if you stored pointers in your vector, in such a case, you need to provide specific behaviour for copy/assignement/destruction to avoid memory leaks or multiple delete.

- 2,637
- 1
- 17
- 15
I can think of a few cases when you need to write your own Big Three. All standard containers know how to copy and destroy themselves, so you don't necessarily need to write them. Here's how to know when you do:
Does my class own any resources?
The default copy semantics for pointers is to copy the value of the pointer, not what it points to. If you need to deep copy something, even if it's stored inside a standard container, you need to write your own copy constructor and assignment operator. You also need to write your own destructor to properly free those resources.
Might someone inherit from my class?
Base classes need a destructor. Herb Sutter recommends making them either public
and virtual
(most common case) or protected
and non-virtual, depending on what you want to do with them. The compiler-generated destructor is public and non-virtual, so you'll have to write your own, even if it doesn't have any code in it. (Note: this doesn't imply you have to write a copy constructor or assignment operator.)
Should I prevent a user from copying objects of my class?
If you don't want the user to copy your objects (maybe that's too expensive), you need to declare the copy constructor and assignment operators either protected
or private
. You don't have to implement them unless you need them. (Note: this doesn't imply you have to write a destructor.)
Bottom line:
The most important thing is to understand what the compiler-generated copy constructor, assignment operator, and destructor will do. You don't need to be afraid of them, but you need to think about them and decide if their behavior is appropriate for your class.

- 34,290
- 15
- 75
- 125
No but there are a number of reasons why you shouldn't allow the compiler to auto generate these functions.
In my experience it is always best to define them yourself, and to get into the habit of making sure that they are maintained when you change the class. Firstly you may well want to put a breakpoint on when a particular ctor or dtor is called. Also not defining them can result in code bloat as the compiler will generate inline calls to member ctor and dtor (Scott Meyers has a section on this).
Also you sometimes want to disallow the default copy ctors and assignments. For example I have an application that stores and manipulates very large blocks of data. We routinely have the equivalent of an STL vector holding millions of 3D points and it would be a disaster if we allowed those containers to be copy constructed. So the ctor and assignment operators are declared private and not defined. That way if anyone writes
class myClass {
void doSomething(const bigDataContainer data); // not should be passed by reference
}
then they'll get a compiler error. Our experience is that an explicit become() or clone() method is far less error prone.
So all in all there are many reason to avoid auto generated compiler functions.

- 565
- 1
- 3
- 10
-
2"get into the habit of making sure that they are maintained when you change the class". That's an unnecessary maintenance nightmare. – fredoverflow Mar 05 '10 at 13:52
-
Should you not have unit tests for your ctors etc to check for correct initialisation? Should you not be considering all the implications of adding data members to classes? If you add a new string to a class what is the impact on code bloat across all the methods that use it, and across all the classes that may contain instances of it? Having added a new member do you not have to reconsider whether allowing autogeneration is viable any more? Whilst you are wondering about all those things adding to the copy-ctor and op= is minimal. – lilburne Mar 05 '10 at 15:34
-
So you'll also need to keep unit tests updated? (It really hasn't occurred to me that I should test assignment of simple classes containing a couple of strings.) - May-be there's something in the code bloat, but in such case, doesn't "optimize for size" options help? – UncleBens Mar 05 '10 at 15:55
those container will need a "copy constructible" element, and if you don't supply the copy constructor, it will call default copy constructor of your class by deducing from your class members (shallow copy).
easy explanation about default copy constructor is here : http://www.fredosaurus.com/notes-cpp/oop-condestructors/copyconstructors.html
it is so with destructor, the container need to have access to your destructor or your default class destructor if you don't provides one (ie. it will not work if you declare your destructor as private )

- 11,254
- 13
- 54
- 74
you need to provide them if you need them. or possible users of your classes. destructor is always a must, and copy constructors and assignment operator are automatically created by compiler. (MSVC at least)

- 59,039
- 12
- 119
- 163
-
1Destructor is also automatic (the compiler won't make them *virtual*, though, but this is another issue). – visitor Mar 05 '10 at 11:49
When ever you have a class that requires deep copies, you should define them.
Specifically, any class which contains pointers or references should contain them such as:
class foo {
private:
int a,b;
bar *c;
}
Subjectively, I would say always define them, as the default behavior provided by the compiler generated version may not be what you expect / want.

- 39,711
- 30
- 131
- 179
-
1May-be it would be better to say: if the class *owns* the resource. As it is, that `bar` instance `c` is pointing to might be owned and controlled elsewhere, and `foo` is just a sharing user of the object. - Interestingly I'd also recommend *not* to define them if the default is OK: you are much more likely to make mistakes than the compiler and break copying and assigning (and in the destructor there's nothing for you to do in the first place in such a case). – visitor Mar 05 '10 at 11:45
-
@visitor: see lilburne's answer - it's basically the same but more detailed in it's reasons - subjectively, I feel that he's right on the money. – Robert S. Barnes Mar 05 '10 at 13:43
-
Naturally you need them if you want anything beyond shallow, memberwise copy. But I'm not entirely convinced why you should do it manually for member-wise copy (which is the majority of classes for me, if they are to be copyable in the first place) - if that is not what you expect, perhaps you expect very bizarre semantics from copying. - Perhaps an objective reason to write assignment operator manually is so you can give stronger exception guarantees (lhv not changed, not just no memory leaked), but I suppose that would be very tricky (need to roll back changes) to be done universally. – visitor Mar 05 '10 at 14:49
Not for strings or vectors, since the trivial constructors / destructors etc, will do fine.
If your class has pointers to other data and need deep copies, or if your class holds a resource that has to be deallocated or has to be copied in a special way.

- 5,657
- 1
- 35
- 60