C++ - 类的赋值操作 使用 "复制-交换(copy and swap) 技术" 详解

类的赋值操作 使用 "复制-交换(copy and swap) 技术" 详解

 

本文地址: http://blog.csdn.net/caroline_wendy/article/details/14645603 

 

如果不包含动态内存分配, 则可以不用设置, 使用合成构造器即可;

如果包含, 则需要自己定义复制-赋值构造器((copy-assignment constructor);

以下三种方法都是 基于 包含动态内存分配,且不使用智能指针(shared_ptr);

 

1. 使用临时变量方法

 

类的复制-赋值操作(copy-assignment operator), 是复制(copy)操作和析构(destruct)操作的集合;

ClassA& ClassA::operator= (....): 首先把"="右边的值复制到"="左边, 然后析构"="左边的值;

为了保证可以自赋值(self-assignment), 需要使用临时变量存储, 再删除对象;

代码如下:

//std::string *ps; ps(new std::string(s));
HasPtr& HasPtr::operator= (const HasPtr &rhs)
{
	auto newp = new std::string( *(rhs.ps) );
	delete ps;
	ps = newp;
	i = rhs.i;
	return *this;
}

2. 使用计数器(counter)方法

 

使用计数器(counter)为了使类的操作, 可以像指针一样传递地址;

不使用"shared_ptr"时,必须使用计数器(counter), 判断使用对象指针数;

使用计数器时, 赋值操作则可以判断计数器的值, 来确定是否删除对象;

自赋值(self-assignment)问题的存在, 所以对于计数器应该 先加后减;

代码如下:

//std::string *ps; ps(new std::string(s));
//std::size_t *use; use(new std::size_t(1));
HasPtr& HasPtr::operator= (const HasPtr &rhs)
{
	++(*(rhs.use)); //括号可以不用添加, 添加是为了清晰
	if (--(*use) == 0) {
		delete ps;
		delete use;
	}
	ps = rhs.ps;
	i = rhs.i;
	use = rhs.use;
	return *this;
}

3. 使用复制-交换(copy-swap)方法

 

复制-交换(copy-swap)方法是利用交换左右两侧的值, 达到赋值的目的;

可以处理自赋值(self-assignment)和异常安全(exception safe);

自赋值问题交给交换(swap)方法; 把异常安全问题交给复制构造器(copy constructor);

注意: 赋值构造器 改变为 只传递实值(value), 不传递常量引用(const &);

使用"using std::swap"的目的是, 如果包含自定义的swap()函数, 则优先使用自定义的swap()函数; 如果未包含, 系统使用标准库的swap()函数;

代码如下:

HasPtr& HasPtr::operator= (HasPtr rhs) {
	using std::swap;
	swap(*this, rhs);
	return *this;
}



  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SpikeKing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值