新塘网站建设,长沙移动网站,微信网站建设方案ppt,静态网站 后台深浅拷贝问题引入浅拷贝深拷贝总结问题引入
对于一个普通的string类#xff1a;
class String {
public:String(const char* str ){//构造函数if (nullptr str)str ;_str new char[strlen(str) 1];strcpy(_str, str);}~String(){//析构函数if …
深浅拷贝问题引入浅拷贝深拷贝总结问题引入
对于一个普通的string类
class String {
public:String(const char* str ){//构造函数if (nullptr str)str ;_str new char[strlen(str) 1];strcpy(_str, str);}~String(){//析构函数if (_str) {delete[] _str;_str nullptr;}}
private:char* _str;
};浅拷贝
对于上述的 String 类来说浅拷贝也就是将一个对象原封不动的复制粘贴到新的对象当中当类中没有给定拷贝构造函数时系统会默认生成一个拷贝构造函数但默认生成的拷贝构造函数就属于浅拷贝 当前系统默认生成的拷贝构造函数类似于 那么浅拷贝是否合理存在
由上述运行截图我们可以观察到使用系统默认生成的拷贝构造函数或是代码中展现的拷贝构造方法构造出来的对象与原对象内容地址是完全一致的也就类似于复制粘贴了一个相同的对象那么它会产生什么问题
在前边类与对象章节中我们知道了在创建的类对象使用结束之后系统会自动调用相应的析构函数来释放资源空间先构造的后释放后构造的先释放因此在该类中首先要进行释放的是 s2后释放 s1我们来看看现象 不知道读者是否发现了问题所在
解析
在使用 s2(s1)s1拷贝构造 s2 对象时我们发现创建出来的 s2 对象完全是复制粘贴 s1 对象而形成的不仅对象内容完全相同对象的地址空间也完全相同这就导致了两个对象是共享同一份地址空间了故在进行析构时产生了同一份地址空间二次释放而发生异常提示 同理在 String 类中倘若用户没有显式定义赋值运算符重载函数则系统会默认生成一个赋值运算符重载函数我们来看看会有什么问题 显然同样产生了浅拷贝复制粘贴则在进行空间销毁时候定会产生空间的二次释放异常那么我们应该如何来解决这种问题
介绍两种技术深拷贝重点、写时拷贝
深拷贝
产生浅拷贝的主要是因为在进行拷贝构造或是赋值运算符重载时直接将就对象的内容原封不动的粘贴给新对象因而在空间释放时形成了多次释放问题因此深拷贝主要就是解决不同对象分配不同地址空间的问题
String(const String s):_str(nullptr){//s2(s1)//首先需要给s2对象开辟一份独立的新空间_str new char[strlen(s._str) 1];//其次将s1对象中的内容拷贝到s2空间当中strcpy(_str, s._str);}同理赋值运算符也是一样的
String operator(const String s){if (this ! s) //判断不是自己给自己赋值{char* tmp new char[strlen(s._str) 1];strcpy(tmp, s._str);delete[] _str; //释放旧空间_str tmp;}return *this;}显然两个对象的地址空间是不相同的则释放空间时不会发生同一份空间多次释放的问题。
现代新写法注意理解
String(const String s):_str(nullptr){//拷贝构造函数String tmp(s._str); //采用当前对象的内容构造出一个新对象tmpswap(_str,tmp._str); //进行资源交换将临时空间 tmp 的内容与 当前对象的内容进行交换------------临时对象在函数周期结束自动析构释放}String operator(String s) { //以值的方式传参需要调用一次拷贝构造函数构造出一个新的对象 s//赋值运算符重载if (this ! s) {swap(_str, s._str); //直接进行交换}return *this;}
总结
在类中倘若用户没有显式定义拷贝构造函数以及赋值运算符重载函数则编译器会自动生成一份但在使用时属于浅拷贝会造成同一份空间多个对象共享在对象使用结束释放空间时会发生多次释放问题产生其次在赋值运算符重载函数中不仅会使得多个对象共享空间还会导致空间丢失问题 String s1(hello); //调用构造String s2 world;//使用系统默认生成的赋值运算符重载函数会导致原有的 s2 对象空间泄漏s2 s1;
因此 我们应该在使用时进行显式的定义防止发生浅拷贝问题的产生
写时拷贝技术
写时拷贝技术同样是针对浅拷贝问题的解决方式
允许多个对象共享同一份地址空间以及空间中的内容并定义一个计数器来统计当前空间所共享的对象个数并在对象使用结束之后在析构函数内部进行计数器 - 1当析构一个对象之后计数器变为 0说明当前对象是共享空间的最后一个使用者则需要对这块空间进行释放--------------------------------但同样存在一个问题倘若某一个对象对这块共享空间的内容进行了修改则其他对象指向的这块共享空间内容也发生了变化
因此写时拷贝技术是在对象需要对共享的内存空间进行修改时拷贝构造出独立的空间来进行修改这么做就不会影响到其他对象对共享空间的访问。
ps 博文内容为原创欢迎各位共同学习~~