一个好的面向对象系统会将内部封装起来,只留两个函数负责拷贝,在必要的时候编译器会自动为我们生成拷贝函数,这些编译默认生成的拷贝函数的行为就是将类的成员全部拷贝一份。
如果你声明自己的拷贝函数,再你增加成员变量的时候,不要忘记修改拷贝函数,因为即使你忘记再你的拷贝函数中添加新的成员变量,编译器并不会报错,在vs2022中会存在警告。
class Customer
{
public:
Customer(const Customer& rhs)
:name(rhs.name)
{}
Customer& opereator=(const Customer& rhs)
{
name = rhs.name;
return *this;
}
private:
std::string name;
};
再添加一个成员变量
class Date
{
private:
int year;
int month;
int day;
};
class Customer
{
public:
Customer(const Customer& rhs)
:name(rhs.name)
{}
Customer& operator=(const Customer& rhs)
{
name = rhs.name;
return *this;
}
private:
std::string name;
Date date;
};
如果忘记在拷贝构造中添加date 会出现一个警告,但是拷贝赋值不会出现警告。

这个条款最重要的部分是在继承体系中。
class PriorityCustomer : public Customer
{
public:
PriorityCustomer()
:priority(0)
{}
PriorityCustomer(const PriorityCustomer& rhs)
:priority(rhs.priority)
{}
PriorityCustomer& operator=(const PriorityCustomer& rhs)
{
priority = rhs.priority;
}
private:
int priority;
};
这个拷贝函数看着没啥问题,实则问题大了,那我问你 你的基类成分去哪了? 你的基类成分难道不需要拷贝吗?
class PriorityCustomer : public Customer
{
public:
PriorityCustomer()
:priority(0)
{}
PriorityCustomer(const PriorityCustomer& rhs)
:Customer(rhs) // 调用基类的拷贝构造
,priority(rhs.priority)
{}
PriorityCustomer& operator=(const PriorityCustomer& rhs)
{
Customer::operator=(rhs); // 调用基类的拷贝赋值
priority = rhs.priority;
}
private:
int priority;
};
用基类的指针或引用接受派生类,没错这就是切片。
1294

被折叠的 条评论
为什么被折叠?



