13.6.3 为HasPtr定义移动构造函数

HasPtr class:

#pragma once
#include <iostream>
#include <string>

class HasPtr {
public:
   HasPtr(const std::string &s, int a)
      : ps(new std::string(s)), i(a) {
      std::cout << "Sting with int constructor execute" << std::endl;
   }

   HasPtr(const std::string &s = std::string())
      : ps(new std::string(s)), i(std::stoi(s)) {
      std::cout << "String constructor execute" << std::endl;
   }

   HasPtr(const HasPtr &obj)
      : ps(new std::string(*obj.ps)), i(obj.i) {
      std::cout << "Copy constructor execute" << std::endl;
   }

   friend void swap(HasPtr &lhs, HasPtr &rhs) {
      std::cout << "HasPtr::swap function execute" << std::endl;
      std::swap(lhs.ps, rhs.ps);
      std::swap(lhs.i, rhs.i);
   }

   HasPtr(HasPtr &&s) noexcept : ps(s.ps), i(s.i) { s.ps = nullptr; }

   HasPtr & operator=(HasPtr s) {
      swap(*this, s);
      return *this;
   }

   ~HasPtr() {
      delete ps;
   }

   std::string get_str() const {
      return *ps;
   }

   int get_i() const {
      return i;
   }

   bool operator<(const HasPtr obj) const {
      std::cout << "Operator < execute" << std::endl;
      return i < obj.i;
   }

private:
   std::string *ps;
   int i;
};

使用移动构造函数为赋值拷贝带来了好处:
复制拷贝运算符的形参不是引用,需要使用拷贝构造函数来传递。如果等号右边的对象是右值,则会使用移动构造函数,将原对象的指针设为空。赋值操作符只需要swap即可,无需指定析构。右值对象出作用域时会自行析构。
main.cpp

int main()
{
   HasPtr a("1"), b("2");
   a = std::move(b);

   return 0;
}

执行过程:
通过两个string构造两个HasPtr对象。a调用复制拷贝运算符,以b为实参通过移动构造函数构造形参。
调用swap函数交换指针。
析构所有对象
在这里插入图片描述
值得一提的是:对空指针调用delete运算符不会产生错误(析构函数会析构那个被move过的原对象,其指针已经被置为空)。delete运算符会检查指针是否为空。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值