1. 程式人生 > >寫時拷貝COW(copy-on-write)

寫時拷貝COW(copy-on-write)

display 語句 namespace div str pre style -a [0

寫時拷貝技術是通過"引用計數"實現的,在分配空間的時候多分配4個字節,用來記錄有多少個指針指向塊空間,當有新的指針指向這塊空間時,引用計數加一,當要釋放這塊空間時,引用計數減一(假裝釋放),直到引用計數減為0時才真的釋放掉這塊空間。當有的指針要改變這塊空間的值時,再為這個指針分配自己的空間(註意這時引用計數的變化,舊的空間的引用計數減一,新分配的空間引用計數加一)。
#include<iostream>
#include<new.h>
#include<string>
using namespace std;

//1解決內存泄漏
//2編寫賦值語句
//3寫時拷貝
class String;
ostream& operator<<(ostream &out, const String &s);

/////////////////////////////////////////////////////////////////////
class String_rep
{
	friend class String;
	friend ostream& operator<<(ostream &out, const String &s);

private:
	String_rep(const char *str = "") : use_count_(0)
	{
		if (str == NULL)
		{
			data = new char[1];
			data[0] = ‘\0‘;
		}
		else
		{
			data = new char[strlen(str) + 1];
			strcpy(data, str);
		}
	}
	String_rep(const String_rep &rep)
	{
		this->data = rep.data;
	}
	String_rep& operator=(const String_rep &rep)
	{
		this->data = rep.data;
	}
	~String_rep()
	{
		if (data != NULL)
		{
			delete[]data;
			data = NULL;
		}
	}
public:
	void increment()
	{
		++use_count_;
	}

	void decrement()
	{
		//引用計數為0,釋放共享內存
		if (--use_count_ == 0)
			delete this;
	}

private:
	char *data;
	int use_count_;
};

//////////////////////////////////////////////////////
class String
{
	friend ostream& operator<<(ostream& out, const String &s);

public:
	String(const char *str = "") :rep(new String_rep(str))
	{
		rep->increment();
	}
	String(const String &s)
	{
		rep = s.rep;
		rep->increment();
	}
	String& operator=(const String &s)
	{
		if (&s != this)
		{
			this->rep->decrement();	  //原有共享內存中的引用計數減一
			this->rep = s.rep;
			this->rep->increment();	  //現有引用計數加一
		}
		return *this;
	}
	~String()
	{
		//String析構一次,引用計數減一
		rep->decrement();
	}

public:
	void to_upper();
	String& operator+=(const String &str);

private:
	String_rep *rep;
};

/////////////////////////////////////////////////////////////////////////
ostream& operator<<(ostream &out, const String &s)
{
	out << s.rep->data;
	return out;
}

//創建新的共享內存原來共享內存中值一樣,然後再修改
void String::to_upper()
{
	String *newStr = new String(this->rep->data);
	this->rep->decrement();
	this->rep = newStr->rep;
	this->rep->increment();

	char *str = this->rep->data;
	while (*str != ‘\0‘)
	{
		*str -= 32;
		++str;
	}
	delete newStr;
}

String& String::operator+=(const String &str)
{
	char *ch = new char[strlen(str.rep->data) + strlen(this->rep->data) + 1];
	strcpy(ch,this->rep->data);
	strcat(ch, str.rep->data);

	this->rep->decrement();
	String_rep *s = new String_rep(ch);
	this->rep = s;
	this->rep->increment();

	return *this;
}

int main()
{
	String s("abc");
	String s1;
	s1 = s; //
	String s2("xyz");
	String s3(s);
	s2.to_upper();
	
	s3 += s2;
	cout << s2 << endl;
	cout << s3 << endl;

	return 0;
}

寫時拷貝COW(copy-on-write)