C++类四个默认函数&深复制&浅复制
学习C++语言的同学都知道,C++中类是有默认的几个函数的,主要是有四个函数:
四个函数
- 默认构造函数:A(void),无参构造函数
- 拷贝(复制)构造函数:A(const A&a)。用一个对象A去为另一个对象赋值。
- 析构函数:~A(void)。释放掉A所占用的空间。
- 赋值函数:A &original = const A&a。使用一个对象a直接为另一个对象赋值。
默认的无参构造函数和析构函数不多讲,大家都很明白,析构函数不用手动调用,是在类生命期结束的时候系统自动调用的,析构函数主要是释放分配的空间的(delete和delete[]有类似之处)。
每个类只有一个赋值函数和一个析构函数,但是构造函数却可以有多个。对于任意的一个类,如果不编写上述四个函数,C++编译器会自动生成上述四个函数。那不仅要问了,既然C++编译器这么智能,为什么我们还要编写这四个函数呢?
因为这些缺省的拷贝构造函数和赋值函数都是采用“值”操作的方式,而不是“位”操作。这会导致什么问题呢?我们可以想一些,如果类中的成员变量使用了堆空间的时候,就会出现操作的是同一个地址的问题,也就是我们所说的深复制和浅复制的问题。
深复制和浅复制
所谓浅复制,就不是对整个对象的按照位的拷贝,而是仅仅拷贝了数值,就像上面所说的,如果这个类对象中有指针类型(堆空间),那么经过拷贝构造后得到的对象和原来的对象所指向的就是同一块内存空间,那这算是拷贝么??
深复制就不一样了,是对整个对象的按照位拷贝,当遇到指针(对空间)类型变量时候,会对整个指针空间拷贝。这样可以得到两个完全不同的对象。
拷贝构造函数和赋值函数
那么还有一个问题就是拷贝构造函数和赋值函数到底有什么区别呢?都是值拷贝,那他俩貌似也就一样吧。拷贝构造函数是在对象被创建时调用的,而赋值函数只能被已经存在了的对象调用。如下式子所示:
String a(“hello”);
String b(“world”);
String c = a; // 调用了拷贝构造函数,最好写成c(a);
c = b; // 调用了赋值函数
总结
当类含有动态生成的数据成员,必须自定义析构函数以释放动态分配的内存,自定义复制构造函数(Copy Structor)和复制赋值操作符(Copy Assignment Operator)实现深复制。
C++类四个默认函数&深复制&浅复制的更多相关文章
- C++(1)C++类四个默认函数---构造函数、析构函数、拷贝函数、赋值函数
C++构造函数和析构函数 默认构造函数指不带参数或者所有参数都有缺省值的构造函数!!! (1)构造函数.析构函数与赋值函数 构造函数.析构函数与赋值函数是每个类最基本的函数.它们太普通以致让人容易麻痹 ...
- 简单理解php深复制浅复制问题
其实接触深复制浅复制是通过学习c++了解到的,比如c++很好用的模板,php是不允许方法模板和类模板 一个简单的例子,如果不是很了解php 的取地址符&,可以去看下官方文档,php的& ...
- C++空类中的默认函数
定义一个空的C++类,例如 class Empty { } 一个空的class在C++编译器处理过后就不再为空,编译器会自动地为我们声明一些member function,一般编译过去就相当于 cla ...
- iOS 深复制&浅复制
1.无论是深复制还是浅复制,被复制的对象类型是不变的.此对象类型具有什么功能就具有什么功能,不会因为自行修改了返回对象的指针类型而改变. 比如: 这里的str和str1的值和指针地址完全一 ...
- java 及 Jquery中的深复制 浅复制
发现问题:最近 遇到由于复制对象之后,改变复制后的新变量,原先被复制的对象居然会跟着变. EX:java中: //holidayConfig.getEnd_time()会随着sTime的改变而改变 s ...
- iOS开发之Copy & MutableCopy及深复制 & 浅复制
1.使用copy或mutableCopy方法可以创建一个对象的副本. copy: (1)需要实现NSCoppying协议 (2)创建的是不可变副本(如NSString.NSArray.NSDictio ...
- C++类指针类型的成员变量的浅复制与深复制
本篇文章旨在阐述C++类的构造,拷贝构造,析构机制,以及指针成员变量指针悬空问题的解决.需要读者有较好的C++基础,熟悉引用,const的相关知识. 引言: 类作为C++语言的一种数据类型,是对C语言 ...
- c++类大四个默认函数-构造函数 析构函数 拷贝构造函数 赋值构造函数
每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝构造函数,其它的称为普通构造函数).对于任意一个类A,如果不编写上述函数,C++编译器将自动为A 产生四个缺省的函数,例如: A ...
- Python深复制浅复制or深拷贝浅拷贝
1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象.(比深拷贝更加节省内存)2. copy.deepcopy 深拷贝 拷贝对象及其子对象 用一个简单的例子说明如下: >& ...
随机推荐
- 【每日scrum】NO.9
(1)这是我们冲刺的最后一天,晚上我们的团队进行了收尾工作:第一阶段的任务基本完成,软件主要实现了校园景点照片以及对应的介绍,查询最短路径,查询涉及相关景点的查询,查询全部路径,基本界面的设计,导航功 ...
- lintcode-425-电话号码的字母组合
425-电话号码的字母组合 Given a digit string excluded 01, return all possible letter combinations that the num ...
- erlang驱动使用mysql-otp
Magnus Ahltorp的Mysql Driver里面介绍emysql的缺陷: 1. 隔离不够好, 2.不能伸缩 mysql-otp使用1个进程1个mysql连接,隔离得很好.推荐使用. mysq ...
- 小工具xml生成记录
public partial class Form1 : Form { public Form1() { InitializeComponent ...
- python常用模块collections os random sys
Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句. 模块让你能够有逻辑地组织你的 Python 代码段. 把相关的代码 ...
- Omeed 线段树
目录 题面 题解 代码 题面 2.12 - - - 题解 大概还是挺妙的? 首先基础分和连击分互不干扰,所以可以分开统计. 基础分的统计比较简单,等于: \[A \sum_{i = l}^{r} p_ ...
- day29:关闭服务|
1. 在centos6系统里,我们可以使用ntsysv关闭不需要开机启动的服务,当然也可以使用chkconfig工具来实现. 写一个shell脚本,用chkconfig工具把不常用的服务关闭.脚本需要 ...
- 【JavaScript】基本类型和引用类型的值、引用类型
一.前言 接着上一篇继续记笔记 二.内容 动态的属性 var person = new Object(); person.name = "Nicholas&qu ...
- 【BZOJ2437】【NOI2011】兔兔与蛋蛋(博弈论,二分图匹配)
[BZOJ2437][NOI2011]兔兔与蛋蛋(博弈论,二分图匹配) 题面 BZOJ 题解 考虑一下暴力吧. 对于每个状态,无非就是要考虑它是否是必胜状态 这个直接用\(dfs\)爆搜即可. 这样子 ...
- redis的数据持久化存储
Redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步到硬盘来保证持久化.Redis支持两种持久化方式: 一.snapshotting(快照)方式快照是默认的持久化方式. ...