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

先讲一下默认拷贝函数:

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

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

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

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

最新文章

  1. EntityFramework 7 smallint short 奇怪问题(已解决)
  2. Python开发【第十九篇】:Python操作MySQL
  3. 【Redis】Redis的基本安装及使用
  4. Laravel 5 事件的使用
  5. select动态增加option
  6. SVG基础
  7. CQRS架构如何实现高性能
  8. jQuery选择表格中的列
  9. img 的 3px
  10. redis内存管理
  11. day1——分割数组
  12. java使用Map做缓存你真的用对了吗?弱引用WeakHashMap了解一下
  13. php 调用天气接口
  14. LeetCode:110_Balanced Binary Tree | 平衡二叉树 | Easy
  15. dxCameraControl控件(拍照)
  16. 如何比sketch和axure更方便地给原型做交互?
  17. ==与Equals的作用
  18. C#构造方法(函数)
  19. oracle 不能是用变量来作为列名和表名 ,但使用动态sql可以;
  20. [BZOJ]BST again

热门文章

  1. Charles抓包https请求
  2. Zoey.Dapper--Dapper扩展之把SQL语句放到文件中
  3. IDEA使用maven创建SSM及其依赖的导入
  4. 如何理解虚拟React的DOM(转)
  5. 使用hexo搭建博客并上传GitHub
  6. day03-Linux操作系统目录结构
  7. 算法训练 最大的算式(DP)
  8. uoj#422. 【集训队作业2018】小Z的礼物(MIn-Max容斥+插头dp)
  9. 暴力【bzoj2208】: [Jsoi2010]连通数
  10. getTasksWithCompletionHandler的用法