拷贝控制和引用计数

#include<iostream>
using std::endl;
using std::cin;
using std::cout;
#include <string>
using std::string;
struct HasPtr_value
{
	//new 返回一个指向对象的指针
	HasPtr_value(string curr = string("")):ptr(new string(curr)){ }
	int data;
	string *ptr;
	HasPtr_value(const HasPtr_value& other)
	{
		ptr = new string;
		*ptr = *other.ptr;
	}
	HasPtr_value& operator = (const HasPtr_value& left)
	{
		//拷贝赋值预算符包含了析构函数和拷贝构造函数
		//同时这个操作必须要保证 一个对象向自己赋值时 也是正确的
		//一个通常的策略是,先将操作符右边的对象赋值到临时对象
		//再从临时对象获取值
		//在这个例子中,如果不这么做,那么this和left的ptrptr是同一个值
		//则直接被销毁了
		string *temp = new string(*left.ptr);
		if (ptr!=NULL)
		{
			delete ptr;
		}
		ptr = new string;
		*ptr = *temp;
		return *this;
	}
	~HasPtr_value()
	{
		if (ptr)
		{
			delete ptr;
		}
	}
};

//类的拷贝控制有两种定义
//1.行为像值一样,表示拷贝之后,原对象和拷贝对象的状态保持独立,一个对象变化并不影响另一对象
//2.行为像指针一样,表示拷贝之后,共享状态,原对象和拷贝对象共享底层资源
struct HasPtr_pointer
{
	string *ptr;
	std::size_t *use;
	HasPtr_pointer(string inti = string()); 
	HasPtr_pointer(const HasPtr_pointer & initArg);
	HasPtr_pointer& operator = (const HasPtr_pointer &left);
	~HasPtr_pointer();
};

HasPtr_pointer::HasPtr_pointer(string inti ) :ptr(new string(inti))
, use(new std::size_t(1))
{
}

HasPtr_pointer::~HasPtr_pointer()
{
	if (--*use == 0)
	{
		delete ptr;
		delete use;
	}
}


//只要是构造函数都可以使用 【初始化列表】,
//【直接初始化】 实际上 使用【函数匹配】来查找最符合参数的构造函数来初始化对象
//【拷贝初始化】使用可以转换成目标对象的对象,将其拷贝至对象
HasPtr_pointer::HasPtr_pointer(const HasPtr_pointer& initArg) :
ptr(initArg.ptr), use(initArg.use)
{
	++*use;
}

//编译器只在一个函数被调用时才检查其是否出错
HasPtr_pointer& HasPtr_pointer::operator = (const HasPtr_pointer &left)
{
	++*left.use;
	//string *temp = new string(*left.ptr);
	if (--*use==0)
	{
		delete ptr;
		delete use;
	}
	ptr = left.ptr;
	return *this;
}

int main()
{
	/*HasPtr_value hasptr1("hasptr1");
	hasptr1 = hasptr1;
	{
		HasPtr_value hasptr2 = hasptr1;
		cout << *hasptr2.ptr << endl;
	}
	cout << *hasptr1.ptr << endl;*/

	HasPtr_pointer pointer1("p1");
	HasPtr_pointer pointer2(pointer1);
	HasPtr_pointer pointer3(pointer2);
	cout << *pointer2.use << endl;
	cout << pointer1.ptr << endl;
	cout << pointer2.ptr << endl;
	cout << pointer3.ptr << endl;
	cout << endl;
	HasPtr_pointer pointer4("p4");
	pointer1 = pointer4;
	cout << *pointer4.use << endl;
	cout << pointer4.ptr << endl;
	cout << pointer1.ptr << endl;
	cout << pointer2.ptr << endl;
	cout << pointer3.ptr << endl;
	cout << *pointer2.use << endl;
	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/sinat_14884161/article/details/53890792
今日推荐