引用计数Reference Count

1. 问题

计数器存放在哪?作为类对象的成员时,遇到拷贝构造时如何处置?

Hasptr p1("Hiya");
Hasptr p2(p1);
Hasptr p3(p1);  //p1,p2,p3指向相同的string

2. 解决方法

每个类对象都有一个引用计数,所有类对象的引用计数保证唯一同步。

class Hasptr
{public://2. 当创建一个对象时,只有一个对象共享状态,将此计数器初始化为1。Hasptr(const std::string &s = std::string()):ps(new std::string(s),i(0),use(new std::size_t(1)))  {}//3. 拷贝构造函数递增共享的计数器,指出给定对象的状态又被一个新的用户所共享。Hasptr(const Hasptr &p):ps(p.ps),i(p.i),use(p.use){++*use}; Hasptr& operator=(const Hasptr&);~Hasptr();
private:std::string *ps;int i;std::size_t *use;//1. 增加一个引用计数,用来记录有多少对象与正在创建的对象共享状态。
}

2. 1 析构函数

析构函数递减计数器,指出共享状态的用户少了一个,如果计数器为0,则析构函数释放状态。

Hasptr ::~Hasptr()
{if(--*use == 0){delete ps;delete use;}
}

2. 2 重载赋值

拷贝赋值运算符递增右侧运算对象的计数器,递减左侧运算对象的计数器。如果左侧运算对象的计数器为0,意味着它的共享状态没有用户了,拷贝赋值运算符就必须销毁状态。

Hasptr& Hasptr::operator=(const Hasptr& rhs)
{++*rhs.use;      //递增右侧对象的引用计数if(--*use == 0)  //递减和检测本对象的引用计数{delete ps;delete use;}ps = rhs.ps;i = rhs.i;use = rhs.use;return *this;
}

3. result

HasPtr h("hi mom!");
HasPtr h2 = h;  // no new memory is allocated, // h and h2 share the same underlying string
HasPtr ret;
ret = h; // HasPtr passed by value, so it is copied
cout << ret.i << "," << *ret.ps << endl;

【参考】

[1] 代码referenceCount.h

C++ Primer 5th笔记(chap 13 拷贝控制)引用计数相关推荐

  1. C++ Primer 5th笔记(chap 13 拷贝控制)合成的移动操作

    1. 出现条件 只有当一个类没有定义任何自己版本的拷贝控制成员,且类的每个非 static 数据成员都可以移动,编译器才会为它合成构造函数或移动赋值运算符. struc X{int i;std::st ...

  2. C++ Primer 5th笔记(chap 13 拷贝控制)三五法则

    1. 三个基本操作可以控制类的拷贝操作 • 拷贝构造函数 • 拷贝赋值运算符 • 析构函数. 新标准还有2个函数: • 移动构造函数(move constructor) • 移动赋值运算符(move- ...

  3. C++ Primer 5th笔记(chap 13 拷贝控制)阻止拷贝

    对于一些类来说,拷贝操作是没有意义的,例如 iostream 类阻止了拷贝,以避免多个对象写入或读取相同的 IO 缓冲. 1. 删除函数deleted function 1.1 定义 通过在函数的参数 ...

  4. C++ Primer 5th笔记(chap 13 拷贝控制)=default

    可以将拷贝控制成员函数定义为 =default 来显示地要求编译器生成合成版本. class Sales_data{public:Sales_data() = default;Sales_data(c ...

  5. C++ Primer 5th笔记(chap 13 拷贝控制) 实例2内存管理

    1. 目标 实现标准库vector类的一个简化版本,只支持string,我们命名为StrVec. 2. 设计思想 2.1 allocator管理每个StrVec对象的内存池, 是一块连续的内存(类型为 ...

  6. C++ Primer 5th笔记(chap 13 拷贝控制)引用限定符

    1. 问题 关于右值和左值引用成员函数,通常在一个对象上调用成员函数,而不管对象是一个左值还是一个右值: string s1 = "a value",s2 = "anot ...

  7. C++ Primer 5th笔记(chap 13 拷贝控制)实例1

    1. Folder和Message的类设计 2. Messager.h class Message {friend void swap(Message&, Message&);frie ...

  8. C++ Primer 5th笔记(chap 13 拷贝控制) 对象移动

    1. 为什么要有对象移动 使用移动而非拷贝对象能够大大提升性能. 一些不能被共享的资源类的对象不能拷贝但是可以移动.eg. IO 类 unique_ptr 类 2. 如何做到对象移动 2.1 什么是右 ...

  9. C++ Primer 5th笔记(chap 13 拷贝控制)移动构造和移动赋值

    1. 移动构造函数和移动赋值运算符 一般来说,拷贝一个资源会导致一些额外的开销.在这种拷贝并非必要的情况下,定义了移动构造函数和移动赋值运算符的类就可以避免此问题. eg. StrVec::StrVe ...

最新文章

  1. React 入门笔记 1
  2. 另辟蹊径,中科院自动化所等首次用图卷积网络解决语义分割难题
  3. C++实现Schmidt施密特正交化算法(附完整源码)
  4. 9.Nexus私服安装配置
  5. linux基础命令chown,Linux常用命令及组件:chown和chmod
  6. java stream 多次读取_多次从具有大量数据的Java InputStream中读取
  7. 【dfs】【bfs】【链表】 求连通分量 (ssl 1759)
  8. matplotlib setting zh-hans
  9. 图像处理之三---摄像头灰度值处理
  10. 有jar包直接加密tcp请求报文_netty(十六)报文加密
  11. 普通地图的六大要素_地图的基本要素是什么 主要是哪三大要素
  12. 计算机网络安全防护教案,计算机网络安全基础教案.DOC
  13. 【短语学习】out of the box的含义和翻译
  14. 基于名字自动化之原理(1)
  15. .与localhost与 .\sqlexpress的区别
  16. JS 微信公众号如何跳转到另一个微信公众号的链接
  17. 溢出的文字如何省略号显示
  18. 当BTC大空头遇上PlusToken,投资竟然成为一门玄学?
  19. img 光盘映像文件已损坏_img文件怎么打开
  20. 项目上线后,接口报错:SELECT command denied to user ‘用户名’ @ localhost‘ for table ‘ ‘

热门文章

  1. 数据库创建表的时候长度的介绍
  2. python局部变量想作用于全局_python 局部和全局作用域
  3. python执行shell命令查看输出_python 运行 shell 命令并捕获输出_python_酷徒编程知识库...
  4. json移除一个元素_leetcode:203.移除链表元素,听说用虚拟头节点会方便很多?
  5. java opengl_java基于OpenGL ES实现渲染实例
  6. DL之FAN:基于人工智能算法偶像和明星渐变卡通形象
  7. Dataset之LSUN:LSUN数据集的简介、安装、使用方法之详细攻略
  8. Py之pdfkit:python的库之pdfkit简介、安装、使用方法详细攻略
  9. Py之cv2:cv2库(OpenCV,opencv-python)的简介、安装、使用方法(常见函数、方法等)最强详细攻略
  10. 《精通Python设计模式》学习结构型之享元模式