拷贝结构函数顾名思义就是复制对象。

先讲一下默认拷贝函数:

默认拷贝就是直接赋值,让程序调用默认拷贝结构函数。

Student p1;

Student p2 = p1//或者Student p2(p1);
程序开始运行时,创建p1对象,p1对象的构造函数从堆中分配空间并赋给数据成员pName,执行,p2=p1时,因为没有定义拷贝构造函数,于是就调用默认拷贝构造函数,
 
使得p2与p1完全一样,并没有新分配堆空间给p2,  p1与p2的pName都是同一个值。析构p2时,将堆中字符串清成空串,然后将堆空间返还给系统;
 
析构p1时,因为这是pName指向的是空串,所以第三行输出中显示的只是Destructing,当执行 delete pName ; 按道理系统应该报错,但在gcc中没有。

重点讲一下,深拷贝和浅拷贝。

这里借鉴一个前辈的例子:(前辈写的很好,大家可以看下)

https://www.cnblogs.com/raichen/p/4752025.html

#include <iostream>
#include <cstring>
class Person
{
public : // 构造函数
Person(char * pN)
{
cout << "一般构造函数被调用 !\n";
m_pName = new char[strlen(pN) + ];
//在堆中开辟一个内存块存放pN所指的字符串
if(m_pName != NULL)
{
//如果m_pName不是空指针,则把形参指针pN所指的字符串复制给它
strcpy(m_pName ,pN);
}
} // 系统创建的默认复制构造函数,只做位模式拷贝
Person(Person & p)
{
//使两个字符串指针指向同一地址位置
m_pName = p.m_pName;
} ~Person( )
{
delete m_pName;
} private :
char * m_pName;
}; void main( )
{
Person man("lujun");
Person woman(man); // 结果导致 man 和 woman 的指针都指向了同一个地址 // 函数结束析构时
// 同一个地址被delete两次
} // 下面自己设计复制构造函数,实现“深拷贝”,即不让指针指向同一地址,而是重新申请一块内存给新的对象的指针数据成员
Person(Person & chs);
{
// 用运算符new为新对象的指针数据成员分配空间
m_pName=new char[strlen(p.m_pName)+ ]; if(m_pName)
{
// 复制内容
strcpy(m_pName ,chs.m_pName);
} // 则新创建的对象的m_pName与原对象chs的m_pName不再指向同一地址了
}

因为编译不同,可能不能通过编译,但这不是重点。

直接利用浅拷贝,m_pName = p.m_pName,后者复制给前者,但资源(堆空间)并未复制给前者,相当于这两个都同时指向同一地址,造成或释放两次内存。

深拷贝上面例子可以看到,会给它新申请一个空间。

注意:(引用)“如果需要析构函数,则一定需要拷贝构造函数和赋值操作符。”

什么情况使用复制构造函数:

类的对象需要拷贝时,拷贝构造函数将会被调用。以下情况都会调用拷贝构造函数:

(1)一个对象以值传递的方式传入函数体

(2)一个对象以值传递的方式从函数返回

(3)一个对象需要通过另外一个对象进行初始化。

同时别人推荐的读的文章:https://blog.csdn.net/fdsafwagdagadg6576/article/details/51723823

想要了解跟多可以了解一下这篇文章:《面向对象进价--拷贝构造函数》

然后可以看下例子:多继承的例子(附详解)

C++有关拷贝构造函数(默认/浅/深拷贝构造函数)的更多相关文章

  1. CPP_类默认函数:构造函数,拷贝构造函数,赋值函数和析构函数

    类默认函数:构造函数,拷贝构造函数,赋值函数和析构函数 // person.h #ifndef _PERSON_H_ #define _PERSON_H_ class Person{ public : ...

  2. C++ //构造函数调用规则 //1.创建一个类,C++编译器会给每个类添加至少3个函数 //默认构造(空实现) //析构函数(空实现) //拷贝函数(值拷贝) //2.如果我们写了有参构造函数 编译器就不会提供默认构造函数 但是会提供拷贝构造函数 //3.如果我们写了拷贝函数 编译器就不再提供 默认 有参 构造函数

    //构造函数调用规则 #include <iostream> using namespace std; //1.创建一个类,C++编译器会给每个类添加至少3个函数 //默认构造(空实现) ...

  3. C++坑点集合 - 1 隐式调用和默认实现的构造函数的坑

    C++是一个编译器会替你在背后做很多事情的语言,包括模板实例化,按需要创造隐式的构造函数,默认构造你没有显式构造的成员,按需进行隐式转换和饮食构造等等,如果没有彻底了解清楚,就容易被这些编译器背后做好 ...

  4. 2.9 C++使用默认参数的构造函数

    总结: 默认参数的构造函数,其默认参数必须置于参数列表的结尾. 设计类的构造函数的时候最好不要同时是用构造函数的重载和带参数的构造函数. 我们可以想象一个这样的场景:某一天书店整理库存,发现了一些非常 ...

  5. C++使用默认参数的构造函数

    我们可以想象一个这样的场景:某一天书店整理库存,发现了一些非常老的书,为了尽快清空库存,店主想了一下,决定开展一个大甩卖活动,所有的这些书全部以五美元的价格出售.此时如果需要尽快将这些书的信息录入到书 ...

  6. C#深入学习笔记 - 可空类型与构造函数默认参数

    在实际开发中或许可能会遇到某个属性需要提供一个默认参数,如果该参数是引用类型的话,可以通过 使用 null 来表示未知的值,但如果是int或 其他值类型的话就有点不好办了,因为如果需要一个int或fl ...

  7. C++之带有默认参数值的构造函数

    在一个类中 ,如果程序员没有写,任何一个构造函数,则编译器将为该类提供一个默认的构造函数,如果程序员对类的构造函数进行了重载,则编译器将不提供默构造函数,这里需要手动书写一个无参的构造函数, 无参的构 ...

  8. C++构造函数初始化列表与构造函数中的赋值的区别

    C++类中成员变量的初始化有两种方式:构造函数初始化列表和构造函数体内赋值. 一.内部数据类型(char,int……指针等) class Animal { public: Animal(int wei ...

  9. 用浅/深拷贝、和HTML5方法解决js对象的引用的问题

    先来看一个例子 例一: var a=[1,2,3]; var b=a; b.push(4); alert(b);//1,2,3,4 alert(a);//1,2,3,4 var a=[1,2,3]; ...

随机推荐

  1. 搭建邮件服务器 Postfix + Dovecot (CentOS)

    最近分配到一台ECS服务器,需要搭建一台邮件服务器. 查了一波资料选择了Postfix (smtp)和 Dovecot(pop3). 推荐教程:http://www.cnblogs.com/zlbei ...

  2. NHibernate NHibernate使用时误区

    NHibernate使用时误区 一.异常: 出现org.hibernate.StaleStateException: Unexpected row count: 0 expected: 1异常的原因: ...

  3. docker常用命令行集锦

    对工作中用到的docker命令行进行一个汇总,方便以后的命令行查询,同时也为了加强记忆,会把工作中用到的命令,持续更新上 1.查看私有仓库都有哪些镜像 curl -X GET http://10.27 ...

  4. rabbitmq常用命令行汇总

    最近处理openstack问题时,碰到了rabbitmq相关的问题,使用相关命令行时,经常去现找相关的帖子,感觉很麻烦,记录下自己定位问题时,用到的一些常用命令行,方便以后问题的查找 1)常用的一些查 ...

  5. linux配置环境变量 - 认识

    环境 ubuntu17.04 终端(就是黑框) 认识  环境变量:$PATH 在 ×××/bin 下的命令,可以不用到指定目录下, 比如:安装hbase后,hbase提供一些shell命令在habse ...

  6. ajax上传json串格式的数据的处理 以及 js操作dom的另一种方式

  7. Android源码树中C代码的编译

    侯 Sir说:“源码之下,了无秘密.” 但有些秘密还是要搞起来了看得更真切,仅从静态代码的体位很难体会到运动时的妙处.因此环境搭好了,下一步就是调试.gdbserver搭配gdb的调试环境走得很顺利, ...

  8. 算法训练 K好数 (DP)

    问题描述 如果一个自然数N的K进制表示中任意的相邻的两位都不是相邻的数字,那么我们就说这个数是K好数.求L位K进制数中K好数的数目.例如K = 4,L = 2的时候,所有K好数为11.13.20.22 ...

  9. [poj 2106] Boolean Expressions 递归

    Description The objective of the program you are going to produce is to evaluate boolean expressions ...

  10. B君的第九题

    B君的第九题 对于一个排列\(a_1, a_2,\dots,a_n\),如果对于一个i满足\(a_{i-1}<a_i>a_i+1\)则称i是一个极大值.我们认为\(a_0=a_{n+1}= ...