简单认识写时拷贝

标题:简单认识写实拷贝

简单解释一下写实拷贝:

首先我们都知道深拷贝需要在堆区开辟一个空间,浅拷贝则会共用一个空间中的数据,此时我们可以通过对浅拷贝与深拷贝的联合使用,在不改变数据的情况下,通过使用浅拷贝就可以实现目的,这样我们就不用浪费空间,在开辟一个空间;在此时我希望需要修改数据时,再单独开辟空间进行修改,让两个数据不再共享一个数据。

简单代码演示
#include <iostream>
#include <string.h>
#include <malloc.h>
using namespace std;

class String;//使用友元函数,先对友元类声明
class String_rep //这个类主要是进行数据存储和提供对数据操作的函数
{
	friend class String; //友元类
public:
	String_rep(const char *str = "") : use_count(0)
	{
		if (!str)
		{
			data = new char(strlen(str) + 1);
			strcpy(data, str);
		}
		else
		{
			data = new char[1];
			data[0] = 0;
		}
	}
	~String_rep()
	{
		delete[] data;
		data = NULL;
	}

public:
    //指向同一个空间的指针增加时use_count +1
	void increment() 
	{
		++use_count;
	}
    //指向同一个空间的指针减少时use_count -1
    //同时能为String类对象的析构函数提供释放空间判断依据
	void decrement() 
	{
		if (--use_count == 0)
		{
			delete this;
		}
	}
	int print_use_count()
	{
		return use_count;
	}
	char *getData()
	{
		return data;
	}

private:
	char *data;//指向存储数据的指针
	int use_count;//
};


class String //这个类主要是判断实行什么样的拷贝方法,并保证不发生数据泄露和重复释放
{
public:
	String(const char *str = "") : rep(new String_rep(str))
	{
		rep->increment();//增加一个String_rep对象use_count +1
	}
	String(const String &s) //拷贝构造
	{
		rep = s.rep;
		rep->increment();//增加一个String_rep对象use_count +1
	}
	String &operator=(String &s) //赋值重载
	{
		if (rep != s.rep)
		{
			rep->decrement();
			rep = s.rep;
			rep->decrement();
		}
	}
	~String()
	{
		rep->decrement();
	}

public:
	int print_use_count1()
	{
		return rep->print_use_count();
	}
	char *print_data()
	{
		return rep->getData();
	}
	//如果数据改变,重新开辟空间或在原空间直接修改,让数据不相干扰
	void toupper()
	{
		if (rep->print_use_count() > 1) //use_count大于1时,重新开辟空间,不然直接在原空间直接改
		{
			rep->decrement();
			String_rep *rep_new = new String_rep(rep->data);
			rep = rep_new;
			rep->increment();
		}
        char *pch = rep->data;
        while(*pch){
            *pch -= 32;
            pch++;
	}

private:
	String_rep *rep;
};

int main()
{
	String s1("hello");
	String s2 = s1;
	String s3("xyz");
	s3 = s2;//s3数据发生改变
	s1.toupper();
	s1.print_data();
	cout << "s1 count = " << s1.print_use_count1() << endl;
	s2.print_data();
	cout << "s2 count = " << s2.print_use_count1() << endl;
	s3.print_data();
	cout << "s3 count = " << s3.print_use_count1() << endl;
	return 0;
}

总结:

写实拷贝在浅拷贝和深拷贝结合下,能在不发生数据泄露的同时还能对空间合理的利用,是一个巧妙编程思想方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里狼~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值