写时拷贝—C++实现
来源:互联网 发布:mac口红豆沙色是哪款 编辑:程序博客网 时间:2024/06/18 10:59
1.什么是写时拷贝
写时拷贝:引用计数器的浅拷贝,也称延时拷贝。
实现原理:写时拷贝是通过“引用计数”实现的,在分配空间的时候多分配出4个字节,用来记录有多少个指针指向这块空间,当有新的指针指向这块空间时,引用计数加1,当要释放这块空间时,引用计数减1,直到引用计数减为0时才真正释放掉这块空间。当有的指针要改变这块空间的值时,再为这个指针分配自己的空间(注意这时的引用计数变化,旧的空间引用计数减1,新分配的空间引用计数加1)。
2.通过写时拷贝实现简单的String类
(一)独立开辟空间进行引用计数
1.动态开辟两个空间,一个用来存放字符串,一个用来计数
2.每次拷贝构造时直接把字符串指针赋给新的String,count++
3.释放String时,count--,然后检查count是否为0,若为0就释放掉str和refCount
下面我们通过写时拷贝(一)实现String类
class String{public:String(char* str="\0"):_str(new char[strlen(str)+1]),_refCount(new int(1)){strcpy(_str, str);}String(String& s):_str(s._str), _refCount(s._refCount){(*_refCount)++;}void Delete(){if (--(*_refCount) == 0){cout << "~String" << endl;delete[] _str;delete _refCount;}}~String(){Delete();}String &operator=(String &s){if (_str != s._str){Delete();_str = s._str;_refCount = s._refCount;(*_refCount)++;}return *this;}private:char* _str;int* _refCount;};我们通过调试观察下:
我们可以这样思考:如果一个对象第一次开辟空间存放字符串再开辟一块新的空间存放新的引用计数,当它拷贝构造其它对象时让其它对象的引用计数都指向存放引用计数的同一块空间,refCount设置成int*就可以啦,但是这种方式有缺陷。
缺陷一:每次new两块空间,创建多个对象的时候效率比较低
缺陷二:它多次分配小块空间,容易造成内存碎片化,导致分配不出来大块内存
所以我们可以对其进行优化,采取第二种方式
(二)同一块空间上进行引用计数
开辟一个空间,前 4个字节用来计数,剩下的用来存放字符串
利用s1拷贝构造s2时,s1,s2指向同一内存块,refcount为指向该内存块的对象数目。
用法步骤同方法(一)。
下面我们通过写时拷贝(二)实现String类
class String{public:String(char* str = ""):_str(new char[strlen(str) + 1 + 4]){*(int*)_str = 1;_str += 4;strcpy(_str, str);}String(const String& s):_str(s._str){++refCount();}~String(){Delete();}String& operator=(const String& s){if (this != &s){Delete();_str = s._str;refCount()++;}return *this;}void Delete(){if (--refCount() == 0){_str -= 4;delete[] _str;}}int& refCount(){return *((int*)_str - 1);}
注意:1).如果引用计数大于1,在写之前必须拷贝这块内存单元,这样就不会影响其他对象使用这块内存了。(因为可能不止一个对象会使用这块内存,修改了自己等于修改了别人,所以再向这块内存写之前必须要确保没有其他对象使用它)。
2).由于计数器存放在了_str首地址-4的地址上,所以在析构时一定要注意全部释放,避免内存泄漏。
- 【C++】浅析浅拷贝,深拷贝及写时拷贝(copy_on_write),模拟实现String类。
- C/C++ — 写时拷贝
- 写时拷贝—C++实现
- C++String深浅拷贝、写时拷贝
- c++深浅拷贝&写时拷贝实现
- 【C++】写时拷贝COW
- 【C++】深拷贝、浅拷贝和写时拷贝
- 模拟实现String类(2)——写时拷贝
- 模拟实现string——写时拷贝
- 【c++】深浅拷贝,引用计数写时拷贝
- 【C++】String_COW(写时拷贝)
- C++::浅拷贝,深拷贝,引用计数的拷贝,写时拷贝
- 模拟实现String类---->写时拷贝
- 写时拷贝的底层实现
- 深拷贝&浅拷贝&写时拷贝
- 【C++】c++写时拷贝Copy On Write
- 【C语言】String类的写时拷贝
- String——写时拷贝
- EXTJS从选择记录中获取值
- Java Map家族简单总结
- react组件间的数据传递
- Matlab求解微分方程数值解
- js高级教程阅读笔记 第四章-变量作用域和内存问题
- 写时拷贝—C++实现
- noi多维数组 15:细菌的繁殖与扩散
- LayUI的元素属性介绍
- Java Calendar使用指南
- win10+python3.6 安装MySQL-python-1.2.5
- 单目标定程序
- Android 位置,大小,旋转,透明度改变的补间动画
- Python 线程同步 线程优先级
- 位域