effective c++ 学习笔记12

本文探讨了面向对象编程中对象复制的注意事项,包括默认的浅拷贝问题可能导致的资源重复引用和内存泄漏。通过示例展示了如何自定义拷贝构造函数和赋值运算符来确保深拷贝,防止意外问题。同时提醒在继承子类时不要忘记处理基类的拷贝。文章强调了复制所有成员变量的重要性,以避免构造的新实例中数据丢失。
摘要由CSDN通过智能技术生成

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

面向对象系统会将对象的内部封装起来,只留两个函数负责对象的copy:即copy构造函数和赋值运算符。

当用户没有实现时,编译器会自动为对象生成这两个函数,对对象的所有参数做值copy,[浅copy]。

因此,对于在构造函数中使用new的class,要额外注意copy构造和赋值运算符。

编译器默认生成的构造函数,并不会copy new出来的对象,只复制了其地址,直接使用编译器生成的函数会有意想不到的问题。

class Account
{
public :
	Account(std::string str ):data_(str) {}
	~Account() {}
	std::string data_;
};
class Customer
{
public:
	Customer(const std::string name,std::string mobile_num):name_(name)
	{
	 	mobile_ = new Account(mobile_num);
	}
	~Customer()
	{
		delete mobile_;
	}
	/*
	Customer(const Customer &rhs):
	name_(rhs.name_)
	{
		mobile_ = new Account(rhs.mobile_->data_);
	}
	*/
  	void Print()
  	{
    	std::cout << name_ << "  mobile account is " << mobile_->data_ << std::endl;
  	}

private:
	std::string name_;
	Account *mobile_;
};
int main(int argc, char const *argv[])
{
  {
    Customer *A =new Customer("ys","13888888888");
    A->Print();
    Customer B(*A);
    delete A;
    B.Print(); // 无法正常打印数据,没有手机号了
  	// 析构B时会Crash ,对同一块内存delete了两次。
  }
  return 0;
}

自定义子类的copy和赋值运算符时不要忽略基类的构造。

class VipCustomer:public Customer
{
 public:
 	VipCustomer(std::string name,double free):Customer(name),free_(free)
 	{

 	}
 	
 	~VipCustomer() {}
 	//VipCustomer(const VipCustomer &rhs):free_(rhs.free_) // error ,not copy Base class ,can not complie
 	VipCustomer(const VipCustomer &rhs):Customer(rhs),free_(rhs.free_)
 	{
 		logCall("drive copy constructor called ");
 	}

 private:
 	double free_;
};

int main(int argc, char const *argv[])
{	
	VipCustomer A("ys",0.4);
	VipCustomer B(A);
	return 0;
}

应copy所有的成员变量。


class Date
{
public :
	Date() {}
	~Date() {}
	int year;
	int month;
	int day;
};
class Customer
{
public:
	Customer(const std::string name):name_(name){}
	~Customer(){}
	Customer(const Customer &rhs):name_(rhs.name_)
	{
		logCall("copy constructor called ");
	}
private:
	void logCall(std::string str)
	{
		std::cout<< Date.year<<"-"<< Date.month<<"-" <<Date.day<<":  "<< str <<std::endl;
	}
private:
	std::string name_;
	Date last_date_;
};

如上,copy构造函数没有复制Date成员变量,会导致构造的新的实例里的Date对象未知。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值