C++ String 写时拷贝
2016-03-24 20:27
387 查看
当类里面有指针对象时,采用简单的赋值浅拷贝,使得两个指针指向同一块内存,则析构两次,存在内存奔溃的问题,因此浅拷贝中利用引用计数。
//引用计数浅拷贝
//写时拷贝
//引用计数浅拷贝
class String { public: String(char*str = "") :_str(new char[strlen(str) + 1]) , _pRefCount(new int(1)) {} String(const String & s) :_str(s._str) , _pRefCount(s._pRefCount) { ++(*_pRefCount); } String &operator=(const String & s) { if (this != &s) { if (--(*_pRefCount) == 0) { delete[]_str; delete _pRefCount; } _str = s._str; _pRefCount = s._pRefCount; ++(*_pRefCount); } return *this; } ~String() { if (--(*_pRefCount)==0) { delete[]_str; } } private: char*_str; int*_pRefCount; };同之前的delete[ ] 一样,当我们为string 分配内存时,总是多分配一个空间来存储引用计数。在每个内存块的前四个字节来存放一个整数,而真正的内容则在其后。
//写时拷贝
class String { public: String(const char*str="") :_str(new char[strlen(str)+5]) { cout << "String()" << endl; _str += 4; _GetRefCount(_str) = 1; strcpy(_str, str); } String(const String &s) :_str(s._str) { cout << "String(const String &s)" << endl; ++_GetRefCount(_str); } String&operator=(const String &s) { if (_str!=s._str) { _Release(); _str = s._str; ++_GetRefCount(_str); } return *this; } ~String() { cout << "~String()" << endl; _Release(); } //写时才拷贝,当两个对象共享一块内存时,若其中的一个需要修改内容,则此时谁修改,谁在另外地方申请新的空间,将之前共用内存块的引用计数减一,将内容复制到新的空间,并把引用计数设置为1. char&operator[](size_t Index) { if (_GetRefCount(_str) > 1) { --(_GetRefCount(_str)); char*tmp = new char[strlen(_str) + 5]; tmp += 4; _GetRefCount(tmp) = 1; strcpy(tmp, _str); _str = tmp; } return _str[Index]; } char* C_Str() { return _str; } private: int& _GetRefCount(char *str) { return *(int*)(str - 4); } void _Release() { if (--_GetRefCount(_str) == 0) { delete[](_str - 4); } } private: char*_str; }; void Test2() { String s1("xello"); String s2(s1); s1[0] = 'h'; cout << s1.C_Str() << endl; cout << s2.C_Str() << endl; } int main() { Test2(); system("pause"); return 0; }
相关文章推荐
- Android之获取手机上的图片和视频缩略图thumbnails
- android string.xml文件中的整型和string型代替
- Android java 与 javascript互访(相互调用)的方法例子
- android上改变listView的选中颜色
- String.intern
- Prototype源码浅析 String部分(二)
- Ruby中的String对象学习笔记
- PostgreSQL ERROR: invalid escape string 解决办法
- 浅谈C++中的string 类型占几个字节
- 标准C++类string的Copy-On-Write技术
- C++实现string存取二进制数据的方法
- C#中string和StingBuilder内存中的区别实例分析
- PHP STRING 陷阱原理说明
- c#中 String和string的区别介绍
- C#实现的图片、string相互转换类分享
- asp.net String.IsNullOrEmpty 方法
- JavaScript中字符串(string)转json的2种方法
- C#中string用法实例详解
- C#中的DataSet、string、DataTable、对象转换成Json的实现代码
- Javascript实现Array和String互转换的方法