只有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:   // 默认

  

C++之拷贝控制 (Copy Control)的更多相关文章

  1. C/C++:copy control (拷贝控制)

    前言:当定义一个类的时候,我们显示或者隐式地指定在此类型的对象拷贝,移动,赋值,销毁时做些什么,一个类通过定义五种特殊的成员函数来控制这些操作,包括拷贝构造函数,拷贝赋值运算符,移动构造函数,移动赋值 ...

  2. [c++] Copy Control

    C++ allows the programmer to define how objects are to be copied, moved, assigned and destroyed. Tog ...

  3. C++的那些事:类的拷贝控制

    1,什么是类的拷贝控制 当我们定义一个类的时候,为了让我们定义的类类型像内置类型(char,int,double等)一样好用,我们通常需要考下面几件事: Q1:用这个类的对象去初始化另一个同类型的对象 ...

  4. C++ Primer : 第十三章 : 拷贝控制之拷贝、赋值与销毁

    拷贝构造函数 一个构造函数的第一个参数是自身类类型的引用,额外的参数(如果有)都有默认值,那么这个构造函数是拷贝构造函数.拷贝构造函数的第一个参数必须是一个引用类型. 合成的拷贝构造函数   在我们没 ...

  5. c/c++ 拷贝控制 构造函数的问题

    拷贝控制 构造函数的问题 问题1:下面①处的代码注释掉后,就编译不过,为什么??? 问题2:但是把②处的也注释掉后,编译就过了,为什么??? 编译错误: 001.cpp: In copy constr ...

  6. c/c++ 拷贝控制 右值与const引用

    拷贝控制 右值与const引用 背景:当一个函数的返回值是自定义类型时,调用侧用什么类型接收?? 1,如果自定义类型的拷贝构造函数的参数用const修饰了:可以用下面的方式接收. Test t2 = ...

  7. 【C++ Primer | 15】构造函数与拷贝控制

    合成拷贝控制与继承 #include <iostream> using namespace std; class Base { public: Base() { cout << ...

  8. 零拷贝-zero copy

    Efficient data transfer through zero copy Zero Copy I: User-Mode Perspective 0. 前言 在阅读RocketMQ的官方文档时 ...

  9. C/C++基础----拷贝控制

    拷贝控制操作,有5个特殊成员函数copy ctor,copy =opt,move ctor,move =opt,dtor 有哪些地方会用到 拷贝初始化 除了=定义变量时 参数传递和函数返回时 花括号列 ...

随机推荐

  1. python之线程和进程(并发编程)

    python的GIL In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native ...

  2. ROS官网新手级教程总结

    第 1 关卡:安装和配置 ROS 环境 目标:在计算机上安装和配置 ROS 环境. 安装 ROS 按照 ROS 安装说明进行安装. 管理环境 确定环境变量 ROS_ROOT 和 ROS_PACKAGE ...

  3. TensorFlow Lite for Android示例

    一.TensorFlow  Lite TensorFlow Lite 是用于移动设备和嵌入式设备的轻量级解决方案.TensorFlow Lite 支持 Android.iOS 甚至树莓派等多种平台. ...

  4. DFS_BFS(深度优先搜索 和 广度优先搜索)

    package com.rao.graph; import java.util.LinkedList; /** * @author Srao * @className BFS_DFS * @date ...

  5. mysql 8创建远程访问用户以及连接mysql速度慢的解决方法

      mysql 8创建远程访问用户 [root@demo /]# mysql -u root -p  #登录服务器数据库 Enter password:123xxx >user mysql; & ...

  6. Centos目录及其常用处理命令

    1.Centos之常见目录作用介绍[1] 我们先切换到系统根目录 / 看看根目录下有哪些目录 [root@localhost ~]# cd / [root@localhost /]# ls bin   ...

  7. JAVA锁的膨胀过程和优化(阿里)

    阿里的人问什么是锁膨胀,答不上来,回来做了总结: 关于锁的膨胀,synchronized的原理参考:深入分析Synchronized原理(阿里面试题) 首先说一下锁的优化策略. 1,自旋锁 自旋锁其实 ...

  8. 【技术博客】Postman接口测试教程 - 环境、附加验证、文件上传测试

    Postman接口测试教程 - 环境.附加验证.文件上传测试 v1.0 作者:ZBW 前言 继利用Postman和Jmeter进行接口性能测试之后,我们发现Postman作为一款入门容易的工具,其内置 ...

  9. 【技术博客】移动端的点击事件与Sticky Hover问题

    目录 移动端的点击事件与Sticky Hover问题 TL;DR 前言 问题描述 背景 实现方式 问题 关于移动端浏览器的点击事件 初次发现问题后各种解决尝试:从点击事件本身下手 cursor: po ...

  10. spring boot2X集成spring cloud config

    Spring Cloud Config 分为 Config Server: 分布式配置中心,是一个独立的微服务应用,用来连接配置服务器并为客户端提供获取配置信息 Config Client: 通过指定 ...