effective c++ 学习笔记11

本文讨论了C++中自我赋值的问题,以CatOwner类为例,展示了如何处理自我赋值操作导致的段错误。通过引入条件检查,避免了直接删除对象并重新分配内存导致的数据丢失。同时,介绍了使用`copy-and-swap` idiom来确保对象在异常情况下也能正确地进行自我赋值,提高了代码的安全性和可靠性。
摘要由CSDN通过智能技术生成

条款11 在operator=中处理自我赋值

继续参考上例,当用户调用方法如下时,会有什么问题?

int main()
{
	Cat A("huahua",5);
	A = A;
}

正常通过。

考虑如下情况


class CatOwner
{
public:
   CatOwner(std::string name = "lily",std::string cat_name ="huahua"):name_(name)
   {
      pcat_ = new Cat(cat_name);
   }
   ~CatOwner() 
   {
   	delete pcat_;
   }
   CatOwner &operator=(const CatOwner &rhs)
   {
      this->name_ = rhs.name_;
      delete this->pcat_;
      this->pcat_ = nullptr;
      this->pcat_ =new Cat(*rhs.pcat_);
      return *this;
   }
  
   void Print()
   {
      if(pcat_ )
         pcat_->Print();
      else
         std::cout << " no cat " << std::endl;
      std::cout << " Owner is " << name_ << std::endl;  
   }
private:
   Cat *pcat_;
   std::string name_; 
};

int main()
{
	CatOwner A("LiLei","leilei");
    CatOwner B("HanMeimei","meimei");
	A = B;
    CatOwner C("LiMing","mingming");
    C =C ;
}

编译通过,执行时,报段错误。原因,调用 C=C 时,先释放了pcat_指针,并修改为nullptr, 访问了空指针。

如下修改

 CatOwner &operator=(const CatOwner &rhs)
 {
   if(*this == rhs)
   	 return *this;
 
   this->name_ = rhs.name_;
   delete this->pcat_;
   this->pcat_ = nullptr;
   this->pcat_ =new Cat(*rhs.pcat_);
   return *this;
 }

编译运行正常。

但,如果在 this->pcat_ =new Cat(*rhs.pcat_); 时抛出异常了,也会导致数据丢失。

再做如下修改

 CatOwner &operator=(const CatOwner &rhs)
 {
    if(*this == rhs)
   	 return *this;
  
   this->name_ = rhs.name_;
 	 Cat *pcat_temp = this-> pcat_;
   this->pcat_ =new Cat(*rhs.pcat_);
   delete pcat_temp;
   pcat_temp = nullptr;
   return *this;
 }

copy and swap

 void CatOwner::swap(const CatOwner &rhs)
 {
   //todo 见条款29
 }
 CatOwner &operator=(const CatOwner &rhs)
 {
   CatOwner Temp(rhs);
   swap(Temp);
   return *this;
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值