C++有关拷贝构造函数(默认/浅/深拷贝构造函数)
拷贝结构函数顾名思义就是复制对象。
先讲一下默认拷贝函数:
默认拷贝就是直接赋值,让程序调用默认拷贝结构函数。
Student p1; Student p2 = p1//或者Student p2(p1);
重点讲一下,深拷贝和浅拷贝。
这里借鉴一个前辈的例子:(前辈写的很好,大家可以看下)
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++有关拷贝构造函数(默认/浅/深拷贝构造函数)的更多相关文章
- CPP_类默认函数:构造函数,拷贝构造函数,赋值函数和析构函数
类默认函数:构造函数,拷贝构造函数,赋值函数和析构函数 // person.h #ifndef _PERSON_H_ #define _PERSON_H_ class Person{ public : ...
- C++ //构造函数调用规则 //1.创建一个类,C++编译器会给每个类添加至少3个函数 //默认构造(空实现) //析构函数(空实现) //拷贝函数(值拷贝) //2.如果我们写了有参构造函数 编译器就不会提供默认构造函数 但是会提供拷贝构造函数 //3.如果我们写了拷贝函数 编译器就不再提供 默认 有参 构造函数
//构造函数调用规则 #include <iostream> using namespace std; //1.创建一个类,C++编译器会给每个类添加至少3个函数 //默认构造(空实现) ...
- C++坑点集合 - 1 隐式调用和默认实现的构造函数的坑
C++是一个编译器会替你在背后做很多事情的语言,包括模板实例化,按需要创造隐式的构造函数,默认构造你没有显式构造的成员,按需进行隐式转换和饮食构造等等,如果没有彻底了解清楚,就容易被这些编译器背后做好 ...
- 2.9 C++使用默认参数的构造函数
总结: 默认参数的构造函数,其默认参数必须置于参数列表的结尾. 设计类的构造函数的时候最好不要同时是用构造函数的重载和带参数的构造函数. 我们可以想象一个这样的场景:某一天书店整理库存,发现了一些非常 ...
- C++使用默认参数的构造函数
我们可以想象一个这样的场景:某一天书店整理库存,发现了一些非常老的书,为了尽快清空库存,店主想了一下,决定开展一个大甩卖活动,所有的这些书全部以五美元的价格出售.此时如果需要尽快将这些书的信息录入到书 ...
- C#深入学习笔记 - 可空类型与构造函数默认参数
在实际开发中或许可能会遇到某个属性需要提供一个默认参数,如果该参数是引用类型的话,可以通过 使用 null 来表示未知的值,但如果是int或 其他值类型的话就有点不好办了,因为如果需要一个int或fl ...
- C++之带有默认参数值的构造函数
在一个类中 ,如果程序员没有写,任何一个构造函数,则编译器将为该类提供一个默认的构造函数,如果程序员对类的构造函数进行了重载,则编译器将不提供默构造函数,这里需要手动书写一个无参的构造函数, 无参的构 ...
- C++构造函数初始化列表与构造函数中的赋值的区别
C++类中成员变量的初始化有两种方式:构造函数初始化列表和构造函数体内赋值. 一.内部数据类型(char,int……指针等) class Animal { public: Animal(int wei ...
- 用浅/深拷贝、和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]; ...
随机推荐
- java读取classpath下properties文件注意事项
1.properties文件在classpath根路径下读取方式 Properties properties = new Properties(); properties.load(BlogIndex ...
- docker安装oracle
最近工作上面遇到一个性能相关的问题,大体描述一下: 批量任务执行的过程中导致数据库sql执行时间过长,查看之后是由于批量任务占满数据库连接池导致的,至于为什么批量任务会不受系统控制导致连接池占满就不说 ...
- SQL 分组后拼接字符串
with t as( select 'Charles' parent, 'William' child union select 'Charles', 'Harry' union select 'An ...
- 本地机器和windows2003远程桌面之间复制粘贴文件
打开远程桌面连接-->选项-->本地资源-->磁盘驱动器 前面打勾然后再连接就可以了.
- 深入浅出git
图文 http://www.cnblogs.com/syp172654682/p/7689328.html 廖雪峰 https://www.liaoxuefeng.com/wiki/001373951 ...
- Python flask虚拟环境安装
1.安装virtualenv 2.在当前路径下创建文件夹,启动虚拟环境 3.在使用虚拟环境前需激活,前面出现(env说明在虚拟环境中).虚拟环境中默认安装了pip,所以直接pip安装flask 4.在 ...
- P3941 入阵曲
\(\color{#0066ff}{ 题目描述 }\) 小 F 很喜欢数学,但是到了高中以后数学总是考不好. 有一天,他在数学课上发起了呆:他想起了过去的一年.一年前,当他初识算法竞赛的 时候,觉得整 ...
- Qt 学习之路 2(1):序
https://www.devbean.net/category/qt-study-road-2/page/10 原来开过QT学习之路1, 很棒, 再翻阅时已经没有了. 所以这次把看过的记录下来 Ho ...
- html td 限制 高度 和 宽度
td 要设置成 display : block td 里面的span 自动换行.. <td style="max-width: 150px;overflow-y:scroll;disp ...
- 简单理解php的socket连接
socket建立套接的过程图: 首先了解socket 几个主要函数: socket的关键函数1: socket_create($net参数1,$stream参数2,$protocol参数3) 作用:创 ...