关于c++深拷贝与浅拷贝
首先看一段代码:
#include<iostream>
#include<cstring>
#include<malloc.h>
using namespace std; class Teacher{
public:
Teacher(int id,char *name){
m_id=id; m_name=(char*)malloc(strlen(name)+);//由于显示析构函数中free内存空间,因而必须malloc
strcpy(m_name,name);
} void Print(){
cout<<"id="<<m_id<<" name="<<m_name<<endl;
} ~Teacher(){/*显示析构函数*/
cout<<"Teacher()..."<<endl;
if(m_name!=NULL){
free(m_name);
m_name=NULL;
}
}
private:
int m_id;
char *m_name;
}; int main(){
Teacher t1(,"zhangsan");
t1.Print(); return ;
}
浅谈析构函数特点:
1.函数名是在类名前加上~,无参数且无返回值。
2.一个类只能有且有一个析构函数,如果没有显式的定义,系统会生成一个缺省的析构函数(合成析构函数)。
3.析构函数不能重载。每有一次构造函数的调用就会有一次析构函数的调用。
#include<iostream>
#include<cstring>
#include<malloc.h>
using namespace std; class Teacher{
public:
Teacher(int id,char *name){
cout<<"Teacher(int,char*)..."<<endl;
m_id=id; int len=strlen(name);
m_name=(char*)malloc(len+);//由于显示析构函数中free内存空间,因而必须malloc
strcpy(m_name,name);
}
/*默认拷贝构造函数,浅拷贝!!!*/
Teacher(const Teacher& another){
m_id=another.m_id;
m_name=another.m_name;
}
void Print(){
cout<<"id="<<m_id<<" name="<<m_name<<endl;
} ~Teacher(){/*显示析构函数*/
cout<<"Teacher()..."<<endl;
if(m_name!=NULL){
free(m_name);
m_name=NULL;
}
}
private:
int m_id;
char *m_name;
}; void test(){
Teacher t1(,"xiaoming");
t1.Print(); Teacher t2(t1);//t2的默认拷贝构造
t2.Print();
} int main(){
test(); return ;
}
【浅拷贝】是增加了一个指针,指向原来已经存在的内存。
而【深拷贝】是增加了一个指针,并新开辟了一块空间,让指针指向这块新开辟的空间

在test函数结束时,t1和t2都会走一遍析构函数,释放内存空间,t2后执行,因而先走析构函数,将name的内存空间释放掉,当t1走析构函数时,会再次进行m_name的内存空间释放,但由于这块内存空间在t2走析构函数时已经被释放掉了,所以在这里会引发段错误!!!,这也就是浅拷贝的危害。。。
为了避免浅拷贝引发的段错误,因而我们需要进行深拷贝,重写拷贝构造函数
#include<iostream>
#include<cstring>
#include<malloc.h>
using namespace std; class Teacher{
public:
Teacher(int id,char *name){
cout<<"Teacher(int,char*)..."<<endl;
m_id=id; int len=strlen(name);
m_name=(char*)malloc(len+);//由于显示析构函数中free内存空间,因而必须malloc
strcpy(m_name,name);
}
/*重写拷贝构造函数,深拷贝*/
Teacher(const Teacher& another){
m_id=another.m_id;
//深拷贝//
int len=strlen(another.m_name);
m_name=(char*)malloc(len+);
strcpy(m_name,another.m_name);
}
void Print(){
cout<<"id="<<m_id<<" name="<<m_name<<endl;
} ~Teacher(){/*显示析构函数*/
cout<<"Teacher()..."<<endl;
if(m_name!=NULL){
free(m_name);
m_name=NULL;
}
}
private:
int m_id;
char *m_name;
}; void test(){
Teacher t1(,"xiaoming");
t1.Print(); Teacher t2(t1);//t2的默认拷贝构造
t2.Print();
} int main(){
test(); return ;
}
关于c++深拷贝与浅拷贝的更多相关文章
- C#设计模式:原型模式(Prototype)及深拷贝、浅拷贝
原型模式(Prototype) 定义: 原型模式:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象.被复制的实例被称为原型,这个原型是可定制的. Prototype Pattern也是一 ...
- Objective-C中的深拷贝和浅拷贝
在Objective-C中对象之间的拷贝分为浅拷贝和深拷贝.说白了,对非容器类的浅拷贝就是拷贝对象的地址,对象里面存的内容仍然是一份,没有新的内存被分配.对非容器类的深拷贝就是重写分配一块内存,然后把 ...
- $.extend()的深拷贝和浅拷贝详细讲解
版权声明:作者原创,转载请注明出处! 语法:jQuery.extend( [deep ], target, object1 [, objectN ] ) 描述: 将两个或更多对象的内容合并到第一个对象 ...
- JavaScript中面向对象的的深拷贝和浅拷贝
理解深拷贝和浅拷贝之前需要弄懂一些基础概念,内存中存储的变量类型分为值类型和引用类型. 1.值类型赋值的存储特点, 将变量内的数据全部拷贝一份, 存储给新的变量. 例如:var num = 123 : ...
- C++深拷贝与浅拷贝
当用一个已初始化过了的自定义类类型对象去初始化另一个新构造的对象的时候,拷贝构造函数就会被自动调用.也就是说,当类的对象需要拷贝时,拷贝构造函数将会被调用.以下情况都会调用拷贝构造函数: (1)一个对 ...
- C++的深拷贝与浅拷贝
对于普通类型的对象来说,它们之间的复制是很简单的,例如:int a=88;int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.下面是一个类对象拷贝的简单例子. #i ...
- Python赋值语句与深拷贝、浅拷贝的区别
参考:http://stackoverflow.com/questions/17246693/what-exactly-is-the-difference-between-shallow-copy-d ...
- [C#进阶系列]专题一:深入解析深拷贝和浅拷贝
一.前言 这个星期参加了一个面试,面试中问到深浅拷贝的区别,然后我就简单了讲述了它们的之间的区别,然后面试官又继续问,如何实现一个深拷贝呢?当时只回答回答了一种方式,就是使用反射,然后面试官提示还可以 ...
- 也来玩玩 javascript对象深拷贝,浅拷贝
经常看到讨论c#深拷贝,浅拷贝的博客,最近js写的比较多, 所以也来玩玩js的对象拷贝. 下面是维基百科对深浅拷贝的解释: 浅拷贝 One method of copying an object is ...
- OC中的深拷贝与浅拷贝
深拷贝(deep copy)与浅拷贝(shallow copy)的定义一直是有争论的. 一种理解是: 所谓的浅拷贝, 就是不完全的拷贝 NSString *s = @"123"; ...
随机推荐
- phpStorm中如何不让其自动添加封闭大括号?
Settings > Editor > General->Smart Keys.
- 图 总结 AI
这个哥们 总结的太好了, 我忍不住就“偷”过来了 人工智能是一门极富挑战性的科学,从事这项工作的人必须懂得计算机知识,心理学和哲学. 人工智能是包括十分广泛的科学,它由不同的领域组成,如机器学习,计算 ...
- (原)DropBlock A regularization method for convolutional networks
转载请注明出处: https://www.cnblogs.com/darkknightzh/p/9985027.html 论文网址: https://arxiv.org/abs/1810.12890 ...
- Linux下通过 rm -f 删除大量文件时报错:Argument list too long
Linux下通过 rm -f 删除大量的小文件时出现类似如下错误信息: -bash: /bin/rm: Argument list too long 如下图所示: 问题原因 如果待删除文件中包含的小 ...
- kali 安装google chrome浏览器(离线手动)
一.官网下载安装包 需要在google官网下载chrome安装包,安装时请仔细选择安装包,.deb的安装包适用于Debian/Ubuntu系统,.rpm适用于 Fedora/openSUSE系统. k ...
- 【转载】vi/vim使用进阶: 指随意动,移动如飞 (一)
vi/vim使用进阶: 指随意动,移动如飞 (一) << 返回vim使用进阶: 目录 本节所用命令的帮助入口: :help usr_03.txt :help motion.txt :hel ...
- linux下反编译android apk
1.所需要的工具 1)apktool,功能:反编译出apk所需要的资源文件和布局设置文件等, 下载地址:https://code.google.com/p/android-apktool/downlo ...
- Hadoop 2.2.0安装和配置lzo
转自:http://www.iteblog.com/archives/992 Hadoop经常用于处理大量的数据,如果期间的输出数据.中间数据能压缩存储,对系统的I/O性能会有提升.综合考虑压缩.解压 ...
- shell脚本并发执行
简单的并发脚本 #!/bin/bash #并发数 count= ; i < ${count}; i++ )) do { commands1 }& done #等待循环结束再执行wait后 ...
- makefile 常用函数
Linux下编译c/c++源码需要编写makefile文件,文章参看 http://blog.sina.com.cn/s/blog_4c4d6e74010009jr.html 一函数的调用语法 二字符 ...