条款12:复制对象时勿忘其每一个一个成分

一个好的面向对象系统会将内部封装起来,只留两个函数负责拷贝,在必要的时候编译器会自动为我们生成拷贝函数,这些编译默认生成的拷贝函数的行为就是将类的成员全部拷贝一份。

如果你声明自己的拷贝函数,再你增加成员变量的时候,不要忘记修改拷贝函数,因为即使你忘记再你的拷贝函数中添加新的成员变量,编译器并不会报错,在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;
};

用基类的指针或引用接受派生类,没错这就是切片。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值