C++String深浅拷贝问题

1.浅拷贝:
//浅拷贝
class String
{
public:
	String(const char* str)
		: _str(new char[strlen(str) + 1])
	{
		strcpy(_str, str);
	}
	//拷贝构造
	String(const String& str)//浅拷贝--s1和s2同时会指向同一块空间。
		: _str(str._str)
	{}

	String& operator =(const String& str)
	{
		if (this != &str)
		{
			_str = str._str;
		}
		return *this;
	}

	~String()
	{
		if (_str)
		{
			delete[] _str;
		}
	}
private:
	char* _str;
};

void TestString()
{
	String s1("hello world!");
	String s2 = s1;//s1和s2同时指向同一块空间,析构时会析构两次,崩溃
}

C++String深浅拷贝问题_第1张图片

2.深拷贝

//传统写法
class String
{
public:
	//String()
	//:_str(new char[1])
	//{
	//	_str[0] = '\0';
	//}
	
	//带缺省参数更好
	String(char* str= "")
		:_str(new char[strlen(str) + 1])
	{
		strcpy(_str, str);
	}
	String(const String& s)
		:_str(new char[strlen(s._str) + 1])
	{
		strcpy(_str, s._str);//复制
	}
	String& operator=(const String&s)
	{
		if (this != &s)  //自己不能给自己赋值
		{
			char* tmp = new char[strlen(s._str) + 1];
			strcpy(tmp, s._str);  //把_str复制给tmp
			delete[] _str;   //[]  删除原来的_str
			_str = tmp;      //再把tmp赋值给新的_str 实现上面的功能

		}
		return *this;
	}

	~String()
	{
		if (_str)//如果不为空,delete
		{
			delete[] _str;
			cout << "~String" << endl;
		}
	}
private:
	char* _str;
};

void TestString1()
{
	String s1("wwwwwwwww");
	String s2(s1);
	String s3;
	s3 = s1;
}

现代写法:

class String
{
public:
	String(char* str = "")//带有缺省参数的构造函数
		:_str(new char[strlen(str) + 1])//开辟strlen(str)+1个空间
	{
		strcpy(_str, str);//String类的用strcpy进行拷贝即可
	}

	String(const String& s)//拷贝构造
		:_str(NULL)
	{
		String tmp(s._str);//先用s构造个临时对象tmp
		swap(_str, tmp._str);//然后进行交换,这样_str就指向了拷贝构造的内容
		//tmp过了作用域后就自动被析构
	}

	String& operator=(String s)//注意没有&,现代写法这里可以创建临时对象
	{
		swap(_str, s._str);//直接swap,
		return *this;
	}

	~String()
	{
		if (_str)
		{
			delete[] _str;
			//cout << "~String()" << endl;
		}
	}

private:
	char* _str;
};

void TestString2()
{
	String s1("xxxxx");
	String s2(s1);
	String s3;
	s3 = s1;
}
C++String深浅拷贝问题_第2张图片





你可能感兴趣的:(C++)