String類引用計數的寫時拷貝
阿新 • • 發佈:2019-01-08
寫時拷貝:
當一個物件被拷貝構造多次,在不改變內容的情況下,多個物件共用同一個空間。
如果某個物件要改變內容,就要另外開闢一塊相同的空間,然後改變這個物件的_str指標,再進行寫操作
#include<iostream> #include<assert.h> using namespace std; //String類的淺拷貝增刪查改(引用計數的寫時拷貝) class String { public: String(const char* str = "") :_str(new char[strlen(str)+1]) ,_ref(new int(1)) ,_size(strlen(str)) ,_capacity(strlen(str)) { strcpy(_str, str); } String(const String& s) :_str(s._str) ,_ref(s._ref) ,_capacity(s._capacity) ,_size(s._size) { (*_ref)++; } ~String() { Release(); } void Release() { if(--(*_ref) == 0) { delete[] _str; delete _ref; } } const char* c_str() { return _str; } void CopyOnWrite()//引用計數的寫時拷貝 { if(*_ref > 1) { char* tmp = new char[_capacity+1]; if (tmp) { strcpy(tmp, _str); _str = tmp; (*_ref)--; _ref = new int(1); } } } void Expand(size_t n) { if (n>_capacity) { _str = (char*)realloc(_str, n+1); assert(_str); _capacity = n; } } void PushBack(char ch) { CopyOnWrite(); if (_size == _capacity) { //因為已經寫時拷貝了,擴容的是自己的空間不是原空間 Expand(_capacity * 2); } _str[_size++] = ch; _str[_size] = '\0'; } char& operator[](size_t pos) { assert(pos<_size); CopyOnWrite(); return _str[pos]; } private: char* _str; int* _ref; size_t _capacity; size_t _size; };