Copy On Write(写时拷贝)使用了“引用计数”,开辟空间时会多开4个字节用于保存引用计数的值。当第一个对象构造时,string的构造函数会根据传入的参数从堆上分配内存,当有其它对象需要这块内存时,这个计数为自动累加,当有对象析构时,引用计数会减一,直到最后一个对象析构,此时的引用计数为0,此时,程序才会真正的Free这块从堆上分配的内存。
引用计数就是string类中写时拷贝的原理!
#include<iostream> #include<Windows.h> #include<list> using namespace std; class String { public: String(const char* str="") :_str(new char[strlen(str)+5]) { _str += 4; strcpy(_str,str); _GetRefCount(_str) = 1;//初始化引用计数 } String(String& s) :_str(s._str) { ++_GetRefCount(_str); } String& operator=(const String&s) { if (this != &s) { this->~String(); _str = s._str; ++_GetRefCount(_str); } return*this; } char& operator[](size_t index) { if (_GetRefCount(_str) > 1) { _Release(); char* tmp = new char[strlen(_str) + 5]; tmp += 4; strcpy(tmp,_str); _GetRefCount(_str) = 1; _str = tmp; } return _str[index]; } ~String() { _Release(); } private: int& _GetRefCount(char* ptr) { return *(int*)(ptr - 4); } void _Release() { if (--_GetRefCount(_str) == 0 ) { delete[] (_str-4); cout << "delete" << endl; } } friend ostream& operator<<(ostream& os, const String& s) { os << s._str; return os; } private: char* _str; }; int main() { system("pause"); return 0; }