Linux操作下String类的实现--引用计数器
1.引用计数器写法一
写法一个人比较喜欢叫他双指针法,因为他是在类里面创建了两个指针来实现的一个是指针_str,另外一个是用来保存指向同一块空间个数的指针_pRefCount.
class String { public: String(char* str = "") :_str(new char[strlen(str) + 1]) , _pRefCount(new int(1)) { strcpy(_str, str); } String(String& s) :_str(s._str) , _pRefCount(s._pRefCount) { ++(*_pRefCount); } String& operator=(const String& s) { /*char* tmp = new char[strlen(s._str) + 1]; strcpy(tmp, s._str); delete[] _str; _str = tmp;*/ //这种写法不符合引用计数器的原理 /*swap(_str, s._str);*/ if (--(*_pRefCount) == 0) { delete[] _str; delete[] _pRefCount; } _str = s._str; _pRefCount = s._pRefCount; ++(*_pRefCount); return *this; } ~String() { if (--(*_pRefCount) == 0) { delete[] _str; delete[] _pRefCount; } } private: char* _str; /*static int _refCount;*///变成静态的以后,需要在类的外面定义 int* _pRefCount; }; //int String::_refCount = 0; void Test1() { String s1("xxx"); String s2(s1); String s3("yyy"); s3 = s2; /*String s4(s3);*/ } int main() { Test1(); system("pause"); return 0; }
这种写法简单易懂,也容易想到,但是由于要开辟两块空间一块大的一块小的,容易造成系统产生很多的内存碎片,所以有了另外一种写法
2.引用计数器写法二
这种写法的思路是在开辟空间时多开辟四个字节的空间,在头部用四个字节的空间来保存指向同一块空间的个数,这样即避免了内存碎片的产生,也使得操作起来更为方便,不要要操作两块空间。
class String { public: String(char* str = "") :_str(new char[strlen(str) + 5]) { *(int*)_str = 1; _str += 4; strcpy(_str, str); } String(String& s) :_str(s._str) { ++(*(int*)(_str - 4)); } String& operator=(const String& s) { if (_str != s._str) { Release(); _str = s._str; ++GetRefCount(_str); } return *this; } ~String() { if (--(*(int*)(_str - 4)) == 0) { delete[](_str - 4); } } int& GetRefCount(char* str) { return *(int*)(str - 4); } void Release() { if (--GetRefCount(_str) == 0) { delete[](_str - 4); } } private: char* _str; }; int main() { system("pause"); return 0; }
时间: 2024-11-08 22:25:53