C++ tip 7: Be sure to copy all of an object's data members and its base class parts
Hi there,
In C++ there are two methods that are in charge of copying objects. They are called:
- Copy constructor
- Copy assignment operator
The following class has a copy constructor and a copy assignment operator:
class Polygon{
public:
//...
//Copy constructor
Polygon(const Polygon& p):name(p.name){}
//Copy assignment operator
Polygon& operator=(const Polygon& p){
name=p.name; //copy p's data
return *this;
}
private:
std::string name;
};
This is nothing new to you. When we call the copy constructor or copy assignment, the data member name is copied onto the new object.
Now, let's say that you add another data member to the class called distance.
class Polygon{
public:
//...
//Copy constructor
Polygon(const Polygon& p):name(p.name){}
//Copy assignment operator
Polygon& operator=(const Polygon& p){
name=p.name; //copy p's data
return *this;
}
private:
std::string name;
float distance;
};
What do you think will happen if you forget to implement the copy of the new data member in both copy constructor and copy assignment?
Yep, you are right. The data member distance will not be copied. One of the tip from the book Efficient C++ is to make sure to copy all of an object's data members.
So an easy fix is as shown below:
class Polygon{
public:
//...
//Copy constructor
Polygon(const Polygon& p):name(p.name),distance(p.distance){}
//Copy assignment operator
Polygon& operator=(const Polygon& p){
name=p.name; //copy p's data
distance=p.distance;
return *this;
}
private:
std::string name;
float distance;
};
This may seem obvious to you but the problem usually arises when you use derived classes. Let's see what happens when you have a derived class and implement a copy constructor and a copy assignment.
class Triangle:Polygon{
public:
//...
//Copy constructor
Triangle(const Triangle& t):coordinate(t.coordinate){}
//Copy assignment operator
Triangle& operator=(const Triangle& t){
coordinate=t.coordinate; //copy t's data
return *this;
}
private:
float coordinate
};
When you do a copy of your derived class, the data members from the base class will not be copied!!! It is your duty to inform the copy methods to also copy the base class's copy constructor and assignment. This is done as follows:
class Triangle:Polygon{
public:
//...
//In the copy constructor invoke the base class copy constructor
Triangle(const Triangle& t):Polygon(t),coordinate(t.coordinate){}
//Copy assignment operator
Triangle& operator=(const Triangle& t){
//inform the base class to copy its data members
Polygon::operator=(t);
coordinate=t.coordinate; //copy t's data
return *this;
}
private:
float coordinate
};
I hope this tip is helpful.
If you want to receive more tips, sign up to my newsletter below.