拷贝构造赋值 & 折构函数 & 三/五法则 & 指针的拷贝管理 & 移动拷贝赋值

构造函数

  1. 初始化类的成员

拷贝构造

  1. 当类对象被其他类对象,或可以隐式转换为类类型,初始化时
  2. 第一个形参为自身类型引用,其余形参均有默认值,的构造函数为拷贝构造函数
  3. 无论我们是否自定义拷贝构造,编译器都会为我们合成默认拷贝构造
  4. 会将每个非static成员,逐个拷贝到正在创建的对象中
  5. 拷贝方式:
    1. 内置类型直接拷贝
    2. 类类型成员根据自己的构造函数
    3. 数组不能拷贝,但可以逐一拷贝数组成员

拷贝初始化 VS 直接初始化

  1. =拷贝初始化,会调用拷贝构造函数
  2. () 直接初始化,会根据重载的函数匹配,来匹配优先级最高的构造函数
  3. 拷贝初始化不仅通过=号,还包括:非&类型形参,非&返回类型,列表初始化数组元素
  4. 因此,拷贝构造的形参需要为&类型,否则发生无休止的递归
  5. 拷贝初始化限制,当构造函数为explicit的类类型转换,我们不能使用=性质发生隐式类类型转换,应用()形式,发生类型转换

拷贝赋值

  1. 当类对象被其他类对象,或可以隐式转换为类类型,赋值时
  2. 本质是重载=号运算符 :class&  operator  =  (const class&),括号内为赋值(=)的右侧运算对象,左侧运算对象&绑定到this,为类对象

折构函数

  1. 不接受参数,不能被重载,每个类只会有唯一的折构函数
  2. 当类对象离开作用域,类对象被销毁,其成员也都被销毁

三/五法则

  1. 需要自定义折构函数的类,也需要自定义拷贝构造和拷贝赋值
  2. 需要自定义拷贝构造的类,也需要自定义拷贝赋值

阻止拷贝

  1. =default ,显示生成默认版本,如果希望是内联,则在类内使用,反之,在类外定义使用
  2. //
  3. 有时我们希望不可以拷贝或赋值类对象,使用=delete表示虽然声明,但不能使用,定义为删除的。
  4. =delete不同于=default,必须出现在第一次声明时,因为编译器需要先禁止使用它的操作
  5. =delete另一个不同于=default,可以对任何函数指定=delete,不必非要时默认的函数
  6. 对于默认版本会受=delete的影响:
    1. 如果类成员(类对象或成员函数)折构是删除或private的,则类的默认折构,拷贝构造,被定义为删除,否则可能会创建无法销毁的对象
    2. 如果类成员拷贝构造函数删除,则默认拷贝构造,被定义为删除,
    3. 如果类成员拷贝赋值函数删除,或者有const或引用成员,则默认拷贝赋值,被定义为删除,
    4. 对于引用来说,因为在=赋值时,我们改变的时引用绑定的值,而非引用绑定其他对象,和我们想要拷贝类对象的每个成员想法违背,所以定义为删除的
    5. 对于const成员不允许 = 赋值操作
    6. 如果引用成员或const成员,没有类内初始值(成员列表初始化 > 类内初始化),那么默认初始化的值是未定义的,类的默认构造函数定义为删除
  7. 老版本通过将拷贝或赋值运算符声明为private来阻止拷贝

指针的拷贝管理

  1. 对于指针= 行为有两种:**p = &p2 (指向指针的指针) || p = p2(指向同一对象,p2指针作为右值取p2的值)
  2. 当默认拷贝构造或拷贝赋值函数的= 操作,为第二种形式,它们指向同一内存,因此会发生,多次delete指针 | 空悬指针的问题,所以我们需要自定义拷贝构造或拷贝赋值
  3. //
  4. 可以使用new动态分配新的堆内存:
  5. 要注意防范自赋值问题:当自赋值,需要先拷贝内存,再delete当前类指针,再为当前类指针指向新的地址,
  6. 而非直接delete当前类指针,不拷贝内存,当我们自赋值时,就已经释放了这两个类的内存,从而变为空悬指针
  7. //
  8. 还有一种方式实现指针的管理:
  9. 使用int计数器模拟shared_ptr的计数操作,当拷贝构造时递增本对象引用计数,当拷贝赋值时递减本对象引用计数,递增&右侧对象引用计数,对于折构,如果计数==0,delete指针

移动拷贝 & 移动赋值

  1. 移动:不发生拷贝,移动资源
  2. 移动拷贝的第一个参数是右值&&引用,它和&不同,将不会分配新的内存
  3. &左值持久,&&右值短暂:&&绑定的必须是临时对象,要被销毁的对象,此对象没有其他用户,可被销毁
  4. 在拷贝构造内,我们会将括号内对象的指针都置为nullptr,源对象会被销毁,本对象存在
  5. 要注意标记为noexcept

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值