标题:简单认识写实拷贝
简单解释一下写实拷贝:
首先我们都知道深拷贝需要在堆区开辟一个空间,浅拷贝则会共用一个空间中的数据,此时我们可以通过对浅拷贝与深拷贝的联合使用,在不改变数据的情况下,通过使用浅拷贝就可以实现目的,这样我们就不用浪费空间,在开辟一个空间;在此时我希望需要修改数据时,再单独开辟空间进行修改,让两个数据不再共享一个数据。
简单代码演示
#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;
}
总结:
写实拷贝在浅拷贝和深拷贝结合下,能在不发生数据泄露的同时还能对空间合理的利用,是一个巧妙编程思想方法。