当类里面有指针对象时,由于浅拷贝是由两个对象指向同一块内存,存在崩溃的问题!为了解决,所以引入了深拷贝、写时拷贝。

1.浅拷贝(新开辟一个指针做引用计数)

//浅拷贝+引用计数(指针)
class String
{
public:
	String(char* str="")//缺省时给定\0
		:_str(new char[strlen(str)+1])
		,_pCount(new int(1))
	{
		strcpy(_str,str);
		*_pCount=1;
	}
	String(String & s)
		:_str(s._str)
		,_pCount(s._pCount)
	{
		(*_pCount)++;
	}
	String& operator=(const String& s)
	{
		if(this!=&s)
		{
			this->_Release();
			_str=s._str;
			_pCount=s._pCount;
			(*_pCount)++;
		}
		return *this;
	}
	~String()
	{
		_Release();
	}
	void Print()
	{
		printf("%s %d\n",_str,*_pCount);
	}
protected:
	char* _str;
	int* _pCount;
	void _Release()
	{
		if(--(*_pCount)==0)
		{
			delete [] _str;
			delete _pCount;
		}
	}
};
int main()
{
	String s("hello");
	s.Print();
	String s1(s);
	s1.Print();
	String s2=s;
	s2.Print();
	system("pause");
	return 0;
}

2.浅拷贝(在原有的字符串中留int数据大小存计数器)

//浅拷贝+引用计数(_str前给一个int数据大小存计数器)
class String
{
public:
	String(char* str="")
		:_str(new char[strlen(str)+5])
	{
		_str+=4;
		strcpy(_str,str);
		_GetCount(_str)=1;
	}
	String(const String& s)
		//:_str(new char[strlen(s._str)+5])//拷贝构造不也是构造吗,为什么不用开辟空间。浅拷贝指向同一块空间,不用开辟
		// :_str(s._str)
	{
		_str+=4;
		_str=s._str;
		_GetCount(_str)+=1;	
	}
	String& operator=(const String& s)
	{
		if(this!=&s)
		{
			this->_Release();
			_str+=4;
			_str=s._str;
			_GetCount(_str)+=1;
		}
			return *this;
	}
	~String()
	{
		_Release();
	}
	void Print()
	{
		printf("%s %d\n",_str,_GetCount(_str));
	}
protected:
	char* _str;
	int Count;
	void _Release()
	{
		if(--_GetCount(_str)==0)
		{
			delete [] (_str-4);
		}
	}
	int& _GetCount(char* str)
	{
		return *((int*)str-1);
	}
};
int main()
{
	String s("hello");
	s.Print();
	String s1(s);
	s1.Print();
	String s2=s;
	s2.Print();
	system("pause");
	return 0;
}

3.深拷贝

//深拷贝
class String
{
public:
	String(char* str="")
		:_str(new char[strlen(str)+1])
	{
		strcpy(_str,str);
	}
	String(const String& s)
		//:_str(new char[strlen(s._str)+1])///这个方法有木有错
		:_str(NULL)
	{
		//strcpy(_str,s._str);
		String tmp(s._str);
		swap(_str,tmp._str);
	}
	String& operator=(const String& s)
	{
		//strcpy(_str,s._str);为什么不可以。2个指针指向同一块空间。1)释放2次。2)一动两变。3)_str原有内存没有释放
		String tmp(s._str);
		swap(_str,tmp._str);
		return *this;
	}
	~String()
	{
		delete [] _str;
	}
	void Print()
	{
		printf("%s\n",_str);
	}
protected:
	char* _str;
};
int main()
{
	String s("hello");
	s.Print();
	String s1(s);
	s1.Print();
	String s2=s;
	s2.Print();
	system("pause");
	return 0;
}

用图来分析一下:wKioL1bzp96QYF5CAAB6iRpf6wo573.png