String类和深浅拷贝

string类和深浅拷贝

c++中将字符串以及操作它的函数单独分装了起来,成为string类,由string类引入深浅拷贝。
一个类中若没有定义拷贝构造函数,就会调用系统默认的拷贝构造函数,比如下面Time类中,没有定义拷贝构造函数

Time t1;
Time t2(t1);  //拷贝t2 = t1;     
t2 = t1;    //赋值
//若没有在类中定义拷贝构造函数和赋值运算符函数,这两种情况都是使t1和t2共享同一块内存

深浅拷贝底层实现:
这里写图片描述

所以编译器默认的拷贝、赋值都是浅拷贝,浅拷贝时会出问题,若在类中定义拷贝构造函数,拷贝时实现的就是深拷贝,既复制了全部成员和数据,也开辟了新空间,析构时,析构自己的空间。

string类深拷贝的传统写法和现代写法(即拷贝构造函数和赋值运算符重载的实现)

拷贝构造函数和赋值运算符函数的传统写法

class String
{
public:
	String(const char *pstr )  //构造函数
	{
		if (pstr = NULL)
		{
			pstr = "";
		}
		else
		{

			str = new char[strlen(pstr) + 1];
			strcpy(str, pstr);
		}
	}
	//拷贝构造函数的实现
	String(const String&s)      
		:str(new char[strlen(s.str) + 1]) //申请新空间
	{
		strcpy(str, s.str);  
	}
	//赋值运算符重载方法一
	String& operator=(const String&s)
	{
		if (this != &s)    //如果不是自己给自己复制
		{

			delete[] str;  //则释放旧空间,因为新的字符可能在旧地之中放不下
			str = new char[strlen(s.str) + 1]; //申请新空间
			strcpy(str, s.str);      //拷贝内容


		}

	}
	/*赋值运算符重载方法二

	String& operator=(const String&s)
	{
		if (this != &s)    //如果不是自己给自己复制
		{

			char *pstr = new char[strlen(s.str) + 1];   //给定新空间
			strcpy(pstr, s.str);
			delete[] str;
			str = pstr;   //交换指向
		}

	}*/

	~String()  //析构函数
	{
		if (str)
			delete[] str;
	}
private:
	char *str;

};

拷贝构造函数和赋值运算符函数的现代写法

class String
{
public:
	String(const char *pstr)  //构造函数
	{
		if (pstr = NULL)
		{
			pstr = "";
		}
		else
		{

			str = new char[strlen(pstr) + 1];
			strcpy(str, pstr);
		}
	}
 
        //拷贝构造函数的实现
		String(const String &s)
			:str(NULL)   //给一个合法的指向
		{
			String strtmp(s.str);
			swap(str, strtmp.str);
		}

        // 赋值运算符重载的三种方法
		String &operator=(const String&s)
		{
			// 方法一
			if (this != &s)
			{
				String strtmp(s.str);
				swap(str, strtmp.str);

			}
			return *this;
		
                //方法二
			/*String strtmp(s);
			swap(str, strtmp); 
			return *this;*/
		}
            //方法三
		//String& operator=(String s)
		//{
		//	swap(str, s.str);
		//	return *this;
		//}

	

	~String()  //析构函数
	{
		if (str)
			delete[] str;
	}
private:
	char *str;

};

void test()
{
	String st1("hello");
	String st2(st1);
	st2 = "world";
	String st3 = st2;            //检测三个空间三个地址是否相同
}

现代方法实现``````对比两者种方法的区别对于拷贝构造函数来说,传统方法需要申请新空间,但现代版不需要,直接创建一个对象,因为对象一旦创建,数据的底层空间就开辟了出来,然后利用交换来实现;对于赋值运算符重载来说,传统版本重点在于释放旧空间,申请新空间,现代版本利用创建对象和交换函数来实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值