C++ Primer 13.6

1.右值引用
&&x
"&&"符号是右值引用符号
相对于左值引用来说,右值引用只能绑定到一个结果,一个临时量、常量上面。而左值引用一般是绑定到一个对象上面,进行地址、身份的绑定。(*表达式是一个左值,同样,变量可以看作没有运算符的表达式)

2.标准库move函数
通过utility中 move函数,可以获得变量的右值引用

int &&rr3 = std::move(rr1);

3.移动构造函数
  如果让自己的类支持移动,而不是拷贝,可以在实际使用中以及特定的条件下节省大量的空间。
  因为“移动”的核心意义是“接管” 而不是复制:
 StrVec::StrVec(strVec &&s) noexcept :
         elements(s.elements),first_free(s.first_free),cap(s.cap)
{
s.elements = s.first_free = s.cap = nullptr;// 使原来的类内指针空置,这样析构函数就不会销毁被“接管”的资源
}

4.移动构造函数和noexcept
移动构造函数及移动构造运算符应声明为 noexcept的
StrVec(Strvec &&) noexcept;

是为了安全以及避免标准库容器(?编译器) 做出额外的工作:
例如vector::push_back 异常时,会进行重新分配空间,并进行拷贝(移动),
但是在我们自定义的类中,如果在移动过程中,移动部分后出现了异常,那么旧的类已经改变,而新的类没有完整生成。会出现不安全的情况?

所以在移动函数中只有声明为noexcept ,使用标准库容器时,才支持移动操作,否则考虑到安全 问题,标准库容器,只能会进行拷贝,而不能进行移动。

5.移动后的原对象,需要保证可以析构

6.拷贝并交换赋值运算符
class HasPtr
{
public:
HasPtr(HasPtr &&p) noexcept : ps(p.ps),i(p.i) { p.ps  = 0;}   // 移动构造函数
HasPtr& opeator=(HasPtr rhs)
{ swap(*this,rhs); retrun *this;}
}
 上面的赋值运算符的参数,HasPtr rhs 是非引用的,所以会进行拷贝初始化,而拷贝初始化使用 拷贝构造函数或者 移动构造函数(根据实参的类型而定)。
当实参是左值的时候,rhs会被拷贝初始化;
当实参是右值的时候,rhs会被移动初始化;

当rhs被初始化之后,通过swap操作,进行交换,这样也能避免额外的开销。而rhs交换离开作用域后,就会被销毁。


7.移动迭代器

通过make_move_iterator 函数将一个普通迭代器,转换为移动迭代器。

对移动迭代器解引用会得到一个右值引用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值