C++里面的深拷贝和浅拷贝
来源:互联网 发布:泰国蛇毒洗面奶知乎 编辑:程序博客网 时间:2024/06/06 00:31
//拷贝有两种:深拷贝和浅拷贝
//1.结构体中的深拷贝和浅拷贝
/*
浅拷贝:编译器仅仅拷贝了结构体的值,而没有创建新的内存空间,而是共享同一块内存空间
。当结构体成员中含有buf的时候,拷贝之后释放内存就不会出现问题,但是如果结构体中含有指针变量时,
编译器就只会拷贝指针变量,而对应
的,内存空间却不会缺,不再多分配。
深拷贝:
编译器会为拷贝的对象分配一定的内存空间
#include <iostream>using namespace std;/* struct Teacher{ string name; int age;}Teacher;int main(){ struct Teacher t1={"cang",18}; struct Teacher t2={"li",20}; t2=t1;//浅拷贝,没有为t2创建内存空间 cout<<"age is:"<<t2.age<<"name is:"<<t2.name<<endl;return 0;}*/
//上面的结构体可以直接使用等于号进行赋值操作;/*#include <iostream>#include <stdio.h>using namespace std; struct Teacher{ int id; char sex; const char *p;}Teacher;int main(){ struct Teacher t1, t2; //const 修饰加上,因为const 存储在常量区,不能被修改,通过指针修改比较危险 //所以通过前面加上const之后,警告消失 const char *str ="i am string"; t1.id = 345; t1.sex = 'y'; //const 修饰的变量只能用const修饰的变量来接收 t1.p = str; t2=t1; printf("t2: %d,%c,%s\n",t2.id,t2.sex,t2.p); //此处打印出来的丢值都是一样的,说明并没有将内容复制一块给新指针, //只是让新的指针指向原来的那个地址,这就相当于,指针在这个过程中只赋值了地值 //而不是内容 printf("s1 ptr:%p,p2 ptr:%p\n",t1.p,t2.p); //这里没有进行运算符重载,所以会出现operator+(); cout<<"t2:"<<t2.id<<t2.sex,t2.p<<endl; cout<<"t1.p:"<<(void *)t1.p<<"t2.p"<<(void *)t2.p<<endl; return 0;}*/
//上面函数的原理:
/*在拷贝过程中,如果没有自定义拷贝构造函数,系统会提供一个缺省的拷贝构造函数
缺省的拷贝构造函数对基本类型的成员变量,按字节赋值,对于类型的成员变量,调用其相应类型的拷贝构造函数
。但是注意缺省的构造函数确实这样的:缺省拷贝构造函数在拷贝过程中是按自己复制的,对于指针变量只赋值指针本身,
而不赋值指针所指项目标======浅拷贝
这就是问题产生的原因: ***********浅拷贝出现了****************************************************
在对对象进行赋值之后,事实上S1,S2的成员都指向同一块内存空间(内存共享)在t1析构时,delete了成员指针所指向的内存空间
而t2被析构时同样指向了(此时这个指针已经变成了野指针)并且要释放这篇已经被t1析构了的内存空间。在同一片空间出现两次释放
自然会出现段错误;
由于内存共享,只要一个子对象改变了其中的值,另一个对象的值也就改变了。
怎么实现深拷贝:
自定义拷贝构造函数
*/
#include <iostream>#include <stdio.h>#include <string.h>using namespace std; struct Teacher{ int id; char sex; char *p; //自定义拷贝构造函数,实现深拷贝 Teacher operator=(Teacher & tec) { id = tec.id;sex = tec.sex;p = new char(strlen(tec.p)+1);strcpy(this->p,tec.p);return *this; }};//相当于重载operator= 方法,这样还是运行,结果就变了int main(){ struct Teacher t1, t2; //const 修饰加上,因为const 存储在常量区,不能被修改,通过指针修改比较危险 //所以通过前面加上const之后,警告消失 char *str ="i am string"; t1.id = 345; t1.sex = 'f'; //const 修饰的变量只能用const修饰的变量来接收 t1.p = (char *)str; t2=t1; printf("t2: %d,%c,%s\n",t2.id,t2.sex,t2.p); printf("s1 ptr stress:%p,p2 ptr stress:%p\n",t1.p,t2.p); printf("s1 ptr:%s,p2 ptr:%s\n",t1.p,t2.p); return 0;}
//类和上面的结构体一致,其实可以将结构体看成一个类来处理,结构体可以有自己的构造,析构,重载运算符,
//可以简单的认为结构体是类的一种形式。
//拷贝函数有两种:深拷贝 浅拷贝
//当出现类的等号赋值时,会调用拷贝函数,在未定义的显示拷贝构造函数的情况下,系统会调用默认的拷贝函数----浅拷贝
//能够完成成员的复制
//当成员数据中没有指针时,浅拷贝是可以的,但当数据成员中有指针时,如果采用简单的浅拷贝,则两类中的两个指针指向同一个地址,
//当对象快结束的时候,会调用两次析构,而导致指针悬挂现象。所以,这时必须采用深拷贝,深拷贝与前拷贝的不同在于
//深拷贝会在堆内存中申请空间来存储数据,从而也就结局了指针悬挂的问题。简而言之,当数据成员中有指针的时候,必须要用
//深拷贝。
//建议:
// 我们在定义类或者是结构体的时候,最后都重写拷贝构造函数,避免浅拷贝;这类不宜发现但后果严重的错误产生。
*/
阅读全文
0 0
- C++里面的深拷贝和浅拷贝
- object c的浅拷贝(地址拷贝)和深拷贝(对象拷贝)
- Object-c 深拷贝和浅拷贝
- [Objective-C]浅拷贝和深拷贝
- 【C++】深拷贝和浅拷贝
- 【C++】深拷贝和浅拷贝
- Objective-C浅拷贝和深拷贝
- 【C++】深拷贝和浅拷贝解析
- C中的深拷贝和浅拷贝
- [c++]深拷贝和浅拷贝
- 【C++】深拷贝、浅拷贝和写时拷贝
- c++中 拷贝构造函数的深拷贝和浅拷贝--“浅拷贝”与“深拷贝”
- Python对象的拷贝,浅拷贝和深拷贝。
- Java的深拷贝和浅拷贝
- Java的深拷贝和浅拷贝
- C++的浅拷贝和深拷贝
- C++的浅拷贝和深拷贝
- Java的深拷贝和浅拷贝
- 深度学习在自然语言处理的应用
- 菜鸟学习微信小程序之数据绑定
- python mysql 字段与关键字冲突解决
- Spring Framework 5.0.0下载
- 算法导论第3章习题解析
- C++里面的深拷贝和浅拷贝
- ssm之helloworld
- 搭建PHP开发环境(四)-PHP操作MySQL
- 单词拼接
- PIXI.js源码解析(2)——Transform
- Eclipse安装Freemarker插件,高亮显示
- 【Maven】发布项目到Tomcat中
- 01-TCP建立连接及状态码
- 【算法设计作业】week2