zoukankan      html  css  js  c++  java
  • C++之拷贝控制 (Copy Control)

    只有2种成员

      值成员;

      指针成员; 依实现可分为raw pointer / shared_ptr;



     现在,仅考虑第③种:资源对象共享 角度来考虑拷贝控制

    类的两种语义:值语义、似指针

     

    编译器提供的default版本的copy constructor/ copy assignment的语义

    0. 默认构造:对每个成员进行默认:① 内置类型、指针类型  若未指定初始值则其值未定义。 ② T类类型成员采用T类型的默认构造。

    1. 拷贝构造: 对rhs的每个成员进行拷贝。(指针成员只拷贝指针值,不进行其指向的资源对象的拷贝)

    2. 拷贝赋值:修改左侧instance的各成员值为右侧对象的对应成员值,即:对lhs的每个成员进行 lhs.member = rhs.member 赋值。


     实现自带的 引用计数器

    实现机制:

      指向同一资源对象instance的多个shared_ptr 联系着同一个 “该资源对象instance的引用计数器”instance 

      【1个引用计数器实例,针对的肯定是 1个资源instance】

      当shared_ptr创建时,引用计数1;拷贝时+1;销毁时-1、并检查:若引用计数变为0,进行资源的释放。

    自行实现:

      类HasPtr通过 *_p 持有一个string对象资源。

      (若该string对象资源 为多个HasPtr的instance-s所共享,则HasPtr的这多个instance-s间共同维护一个的“该string instance的引用计数器”)

      shared_ptr<Resource>  = {
    
          Resource*  pt;   
    
          int*  referCount;
    
      }

     


    4种可能的 拷贝构造/拷贝赋值/析构 方案

    若对某个成员是“值副本持有”:( {T* _pt;  T instance} 视作一体

      copy constructor:拷贝该部分成员资源

          T:     t (rhs.t);    // 默认行为

          *pt:      pt = new T(*rhs.t);

          shared_ptr:    sp = make_shared<T>(*rhs.sp);

      copy = :拷贝该部分成员资源;释放原资源

          T:     t = rhs.t;    // 默认行为

          *pt:      T*  newpt = new T(*rhs.t);   delete pt;  pt = newpt;    // 可优化吧(指针值相等则不拷贝)

          shared_ptr:     sp = make_shared<T>(*rhs.sp);                              // sp.reset(new T(*rhs.sp));也行吧?

      move constructor:接管临时对象的instance资源

          T:     t( move(rhs.t))

          *pt:      pt = rhs.pt;   rhs.pt = nullptr;

          shared_ptr:    sp(rhs.sp)    // 默认行为

      move = : 接管临时对象的资源

          T:    t = move(rhs.t);           // 匹配T instance的move assignment

          *pt:    delete pt;  pt = rhs.pt;   rhs.pt = nullptr;

          shared_ptr:   sp = rhs.sp;     // 默认行为

      析构

          T:    // 默认即可

          *pt:    delete pt; 

          shared_ptr:   // 默认即可

      

    =====================================================================

    若对某个成员属于“作为引用者之一”:(成员不可能是 T t; 形式

      copy constructor:指针绑上

          *pt:      pt( rhs.pt);       // 默认

          shared_ptr:         sp( rhs.sp);          // 默认

      copy = : 指针绑上

          *pt:       pt = rhs.pt;    // 默认

          shared_ptr:   sp = rhs.sp;    // 默认

      move constructor

          *pt:      pt (rhs.pt);    //默认

          shared_ptr:    sp (rhs.sp)      // 默认

      move = :

          *pt:      pt = rhs.pt;    // 默认

          shared_ptr:    sp = rhs.sp;    // 默认

      析构

          *pt:      //默认即可。析构函数中不能写定delete pt;  需要在最后一个对象使用结束后 显式释放

          shared_ptr:   // 默认

      

  • 相关阅读:
    利用Python进行数据分析(3) 使用IPython提高开发效率
    利用Python进行数据分析(2) 尝试处理一份JSON数据并生成条形图
    利用Python进行数据分析(1) 简单介绍
    在真机调试 iOS 应用:理解 Certificates, Identifiers & Profiles
    iOS: 在iPhone和Apple Watch之间共享数据: App Groups
    iOS: 在UIViewController 中添加Static UITableView
    iOS Interface Builder:在.xib文件中加载另一个.xib文件
    在项目中同时使用Objective-C和Swift
    iOS: 为画板App增加 Undo/Redo(撤销/重做)操作
    在iOS中实现一个简单的画板App
  • 原文地址:https://www.cnblogs.com/nanlan2017/p/9241587.html
Copyright © 2011-2022 走看看