首先看一段代码:

 #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++深拷贝与浅拷贝的更多相关文章

  1. C#设计模式:原型模式(Prototype)及深拷贝、浅拷贝

    原型模式(Prototype) 定义: 原型模式:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象.被复制的实例被称为原型,这个原型是可定制的. Prototype Pattern也是一 ...

  2. Objective-C中的深拷贝和浅拷贝

    在Objective-C中对象之间的拷贝分为浅拷贝和深拷贝.说白了,对非容器类的浅拷贝就是拷贝对象的地址,对象里面存的内容仍然是一份,没有新的内存被分配.对非容器类的深拷贝就是重写分配一块内存,然后把 ...

  3. $.extend()的深拷贝和浅拷贝详细讲解

    版权声明:作者原创,转载请注明出处! 语法:jQuery.extend( [deep ], target, object1 [, objectN ] ) 描述: 将两个或更多对象的内容合并到第一个对象 ...

  4. JavaScript中面向对象的的深拷贝和浅拷贝

    理解深拷贝和浅拷贝之前需要弄懂一些基础概念,内存中存储的变量类型分为值类型和引用类型. 1.值类型赋值的存储特点, 将变量内的数据全部拷贝一份, 存储给新的变量. 例如:var num = 123 : ...

  5. C++深拷贝与浅拷贝

    当用一个已初始化过了的自定义类类型对象去初始化另一个新构造的对象的时候,拷贝构造函数就会被自动调用.也就是说,当类的对象需要拷贝时,拷贝构造函数将会被调用.以下情况都会调用拷贝构造函数: (1)一个对 ...

  6. C++的深拷贝与浅拷贝

    对于普通类型的对象来说,它们之间的复制是很简单的,例如:int a=88;int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.下面是一个类对象拷贝的简单例子. #i ...

  7. Python赋值语句与深拷贝、浅拷贝的区别

    参考:http://stackoverflow.com/questions/17246693/what-exactly-is-the-difference-between-shallow-copy-d ...

  8. [C#进阶系列]专题一:深入解析深拷贝和浅拷贝

    一.前言 这个星期参加了一个面试,面试中问到深浅拷贝的区别,然后我就简单了讲述了它们的之间的区别,然后面试官又继续问,如何实现一个深拷贝呢?当时只回答回答了一种方式,就是使用反射,然后面试官提示还可以 ...

  9. 也来玩玩 javascript对象深拷贝,浅拷贝

    经常看到讨论c#深拷贝,浅拷贝的博客,最近js写的比较多, 所以也来玩玩js的对象拷贝. 下面是维基百科对深浅拷贝的解释: 浅拷贝 One method of copying an object is ...

  10. OC中的深拷贝与浅拷贝

    深拷贝(deep copy)与浅拷贝(shallow copy)的定义一直是有争论的. 一种理解是: 所谓的浅拷贝, 就是不完全的拷贝 NSString *s = @"123"; ...

随机推荐

  1. Socket.IO学习之基础入门

    原文:http://blog.csdn.net/weichuang_1/article/details/48831957 这里贴出Socket.IO官网 一.Socket.IO的介绍 Socket.I ...

  2. webpack 配置缓存

    1.输出文件的文件名 加hash 2.提取引导模板 3.模块标识符 https://webpack.docschina.org/guides/caching/#src/components/Sideb ...

  3. spring+springmvc+ibatis整合注解方式实例

    需求说明 实现用户通过数据库验证登录需求.採用 Myeclipse+Tomcat 6.0+Mysql 5.0+JDK 1.6 2.数据库表 开发所用是Mysql数据库,仅仅建立单张用户表T_USER, ...

  4. 【PMP】项目整合管理

    项目整合的七个过程组: 制定项目章程 制定项目管理计划 指导语管理项目工作 管理项目知识 监控项目工作 实施整体变更控制 结束项目或阶段 1.制定项目章程 1.1 定义 制定项目章程是编写一份正式批准 ...

  5. mac下安装xampp、及其之上的组件安装

    由于mac下开发需要用到php7,这里是用的xampp集成开发版本.但是mac下安装xampp失败,失败信息如下: Error starting "XAMPP" stack: fa ...

  6. 【理论面试篇】收集整理来自网络上的一些常见的 经典前端、H5面试题 Web前端开发面试题

    ##2017.10.30收集 面试技巧 5.1 面试形式 1)        一般而言,小公司做笔试题:大公司面谈项目经验:做地图的一定考算法 2)        面试官喜欢什么样的人 ü  技术好. ...

  7. CentOS5.5上安装Python2.7及ez_setup和pip包

    CentOS5.5上安装Python2.7及ez_setup和pip包 下载 首先从Python官方下载源代码包下载 编译安装 这里将python安装到/opt/python27文件夹下 tar xv ...

  8. 【转载】vi/vim使用进阶: 指随意动,移动如飞 (二)

    本节所用命令的帮助入口: :help usr_03.txt :help motion.txt :help usr_29.txt :help scroll.txt :help folding 上一篇文章 ...

  9. 【Spark深入学习 -16】官网学习SparkSQL

    ----本节内容-------1.概览        1.1 Spark SQL        1.2 DatSets和DataFrame2.动手干活        2.1 契入点:SparkSess ...

  10. RapidJson 的使用

    rapidjson为了最大化性能,大量使用了浅拷贝,使用之前一定要了解清楚.如果采用了浅拷贝,特别要注意局部对象的使用,以防止对象已被析构了,却还在被使用. rapidjson使用注意点: 1.对不存 ...