自动生成的拷贝构造函数会帮我们将对象的所有部分都进行拷贝,如果我们自己声明拷贝构造函数:
void logCall(const std::string& funcName);
class Customer
{
public:
...
Customer(const Custom& rhs);
Customer& operator=(const Custom& rhs);
...
private:
std:string name;
};
Customer::Customer(const Customer& rhs)
: name(rhs.name)
{
logCall("Customer copy constructor");
}
Customer& Customer::operator=(const Custom& rhs)
{
logCall("Customer copy assignment operator");
name = rhs.name;
return *this;
}
手动生成拷贝构造函数,希望外界对他们的调用会被log记录下来。
这里一切看起来都很好,直到我们加入另外一个成员变量:
class Date() {...};
class Customer
{
public:
...
private:
std::string name;
Date lastTransaction;
};
这时如果我们不更新上面的两个函数的话, 新加入的lastTransaction 就没有被复制,结论就是,如果我们自己生成了拷贝函数,在添加新的成员变量之后,拷贝函数也需要相应的被修改。
一旦发成了继承,会导致一个危机:
class PriorityCustomer : public Customer
{
public:
...
PriorityCustomer(const PriorityCustomer& rhs);
PriorityCustomer& operator=(const PriorityCustomer& rhs);
...
private:
int priority;
};
PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs)
: priority(rhs.priority)
{
logCall("PriorityCustomer copy constructor");
}
PriorityCustomer& PriorityCustomer::operator=(const PriorityCustomer& rhs)
{
logCall("PriorityCustomer copy assignment operator");
priority = rhs.priority;
return *this;
}
PriorityCustomer的拷贝构造函数复制了声明的所有成员变量,但是他从父类继承的成员变量却没有被复制,所以你还需要显式的调用父类的拷贝构造函数:
class PriorityCustomer : public Customer
{
public:
...
PriorityCustomer(const PriorityCustomer& rhs);
PriorityCustomer& operator=(const PriorityCustomer& rhs);
...
private:
int priority;
};
PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs)
: Customer(rhs)
, priority(rhs.priority)
{
logCall("PriorityCustomer copy constructor");
}
PriorityCustomer& PriorityCustomer::operator=(const PriorityCustomer& rhs)
{
logCall("PriorityCustomer copy assignment operator");
Curtomer::operator=(rhs);
priority = rhs.priority;
return *this;
}
所以每当我们自己编写拷贝函数,需要做到
- 复制所有的local变量
- 调用base class的拷贝函数