A copy constructor is a special member function inside a class.
It accepts a reference to an existing object of the same class type and makes a deep copy of that object.
A not only copies all member fields but also copies any dynamically allocated memory.
C++ compilers do copy construction automatically. You need to define a copy constructor when your class involves dynamic memory.
1Review when to call a copy constructor.
There are three situations:
i>when creating an object from an existing object of the same type,
ii>when you pass an object by value to a function and
iii>when a function returns an object.
2.Know when your C++ class needs a copy constructor.
If your class has pointers and it performs dynamic memory allocation, then you must give it an explicit copy constructor.
3.Look at an example ,
3.Look at an example ,
where you don't have to define a constructor for a C++ class.
Class X has only stack variables and no pointers. A shallow copy is sufficient to copy the values of an existing object to a new object.
The compiler can do this automatically, so you don't have to define a copy constructor for class X:
Ex:
class X{
int num;
class X{
int num;
public:
X(): num(0){}
~X();
};
4
Study an example that requires an explicit copy-constructor definition. As you can see, the size of the string, N, isn't a hard-coded value but is determined by the user. To create B from A as in the expression "Z B(A)," you have to tell the compiler how much memory to allocate for B. The place to do this is in the copy constructor, as follows:
class Z{
int N;
char* str;
public:
Z(int n): N(n){
str = new char [N];
}
Z(Z& other){
str = new char [other.GetLen()];
// copy data from the str of "other" to the str of "this"
}
~Z(){
delete [] str;
}
int GetLen() const {
return N;
}
};
Tips & Warnings
Imagine you omit the copy constructor in Z. When you do Z B(A), the compiler will do a shallow copy. This means, the str of B will now have the address value of the str of A, which points to string "Hello\0" somewhere in the heap. If A gets deleted, the str of B will point to nowhere. If you try to print the str of B, you get an access violation. So make sure you make explicit copy constructors where you have to.
X(): num(0){}
~X();
};
4
Study an example that requires an explicit copy-constructor definition. As you can see, the size of the string, N, isn't a hard-coded value but is determined by the user. To create B from A as in the expression "Z B(A)," you have to tell the compiler how much memory to allocate for B. The place to do this is in the copy constructor, as follows:
class Z{
int N;
char* str;
public:
Z(int n): N(n){
str = new char [N];
}
Z(Z& other){
str = new char [other.GetLen()];
// copy data from the str of "other" to the str of "this"
}
~Z(){
delete [] str;
}
int GetLen() const {
return N;
}
};
Tips & Warnings
Imagine you omit the copy constructor in Z. When you do Z B(A), the compiler will do a shallow copy. This means, the str of B will now have the address value of the str of A, which points to string "Hello\0" somewhere in the heap. If A gets deleted, the str of B will point to nowhere. If you try to print the str of B, you get an access violation. So make sure you make explicit copy constructors where you have to.