【C++基础 02】深拷贝和浅拷贝
我的主题是。每天积累一点点。
===========================================
在类定义中,假设没有提供自己的拷贝构造函数,则C++提供一个默认拷贝构造函数。
C++提供的默认拷贝构造函数的工作方法是:完毕一个成员一个成员的拷贝。假设成员是类对象,则调用其拷贝构造函数或者默认拷贝构造函数。须要注意的是。默认拷贝构造函数不会处理静态成员变量。
简单的自己定义拷贝构造函数:
class Student{
public:
//拷贝构造函数
Student(Student& s)
{
a = s.a;
}
protected:
int a;
};
如上,我们拷贝的策略是一个一个成员的拷贝,可是假设一个类拥有资源,当其构造函数分配了一个资源(如堆内存),而拷贝构造函数没有去分配该资源。那么两个对象都拥有同一个资源,这称为浅拷贝。
浅拷贝的一个问题是,当对象析构的时候,该资源将经历两次资源返还。比方以下这样子:
class Person
{
public:
Person(char* pN)
{
cout<<"Constructing"<<pN<<endl;
pName = new char[strlen(pN) + 1];
if(pName != 0)
{
strcpy(pName,pN);
}
}
~Person()
{
cout<<"Destructing"<<pName<<endl;
delete pName;
pName = NULL;
}
protected:
char* pName;
}; void main()
{
Person p1("fzll");
Person p2 = p1; //调用默认拷贝函数
} //输出信息
Constructing fzll
Destructing fzll
Destructing
Null pointer assignment
能够看到,第二次释放资源的时候,出错了。
由于默认拷贝构造函数并没有分配新的资源。
所以我们须要自己定义拷贝构造函数。并分配资源,使拷贝和被拷贝的对象指向不同的资源,这就是深拷贝的概念。C++提供的默认拷贝构造函数就是浅拷贝。
详细例如以下:
class Person
{
public:
Person(char* pN)
{
cout<<"Constructing"<<pN<<endl;
pName = new char[strlen(pN) + 1];
if(pName != 0)
{
strcpy(pName,pN);
}
}
Person(Person& p)
{
cout<<"CopyPerson "<<p.pName<<endl;
pName = new char[strlen(p.pName) + 1];
if(pName != 0)
{
strcpy(pName,p.pName);
} }
~Person()
{
cout<<"Destructing"<<pName<<endl;
delete pName;
pName = NULL;
}
protected:
char* pName;
}; void main()
{
Person p1("fzll");
Person p2 = p1; //调用自己定义拷贝函数
} //输出信息
Constructing fzll
CopyPerson fzll
Destructing fzll
Destructing fzll
堆内存是最经常使用的须要构造拷贝的资源,还有其他资源。比方文件的打开,设备的占有(如打印机)服务业须要深拷贝。
一个非常好的经验是:假设你的类须要析构函数来释放资源。那么它也须要一个拷贝构造函数(深拷贝的方式)。
==============================================================
转载请注明出处:http://blog.csdn.net/shun_fzll/article/details/37774495
【C++基础 02】深拷贝和浅拷贝的更多相关文章
- Java基础(十三)--深拷贝和浅拷贝
在上篇文章:Java基础(十二)--clone()方法,我们简单介绍了clone()的使用 clone()对于基本数据类型的拷贝是完全没问题的,但是如果是引用数据类型呢? @Data @NoArgsC ...
- JavaScript基础之--- 深拷贝与浅拷贝
理解深拷贝和浅拷贝之前,先来看一下JavaScript的数据类型. 1.基本类型和引用类型 //案例1 var num1 = 1, num2 = num1; console.log(num1) con ...
- .NET基础知识之八——深拷贝,浅拷贝
目录 1.概念 2.使用赋值符号"=" 3.浅复制 4.深复制 5.问题一:如果类里面嵌套有多个类,然后嵌套类里面又嵌套类,那么像上面实现深拷贝的方法还能用吗? 6.问题二:实现深 ...
- Python基础-字符串、集合类型、判断、深拷贝与浅拷贝、文件读写
字符串 1.定义三个变量: 2.交换两个变量值 1)引入第三个变量: 2)Python引入第三方变量: 3)不引入第三方变量: 3. isalpha 是否是汉字或字母 4.Isalnum 是否是汉字 ...
- C++基础-4-封装(构造函数与析构函数,深拷贝与浅拷贝,静态成员,this,友元,const修饰成员函数)
4. 封装 4.1.1 封装的意义 1 #include<iostream> 2 #include<string> 3 using namespace std; 4 5 con ...
- JavaScript中面向对象的的深拷贝和浅拷贝
理解深拷贝和浅拷贝之前需要弄懂一些基础概念,内存中存储的变量类型分为值类型和引用类型. 1.值类型赋值的存储特点, 将变量内的数据全部拷贝一份, 存储给新的变量. 例如:var num = 123 : ...
- 也来玩玩 javascript对象深拷贝,浅拷贝
经常看到讨论c#深拷贝,浅拷贝的博客,最近js写的比较多, 所以也来玩玩js的对象拷贝. 下面是维基百科对深浅拷贝的解释: 浅拷贝 One method of copying an object is ...
- 设计模式_11_原型模式(prototype)深拷贝、浅拷贝
设计模式_11_原型模式(prototype) 浅拷贝: package designPatternOf23; /** * 定义:用原型实例,指定创建对象的种类,并通过拷贝这些原型创建新的对象 * P ...
- 浅析C#深拷贝与浅拷贝
1.深拷贝与浅拷贝 拷贝即是通常所说的复制(Copy)或克隆(Clone),对象的拷贝也就是从现有对象复制一个“一模一样”的新对象出来.虽然都是复制对象,但是不同的 复制方法,复制出来的新对象却并 ...
- 浅析C#深拷贝与浅拷贝(转)
1.深拷贝与浅拷贝 拷贝即是通常所说的复制(Copy)或克隆(Clone),对象的拷贝也就是从现有对象复制一个“一模一样”的新对象出来.虽然都是复制对象,但是不同的 复制方法,复制出来的新对象却并 ...
随机推荐
- (转)Spring的三种实例化Bean的方式
http://blog.csdn.net/yerenyuan_pku/article/details/52832793 Spring提供了三种实例化Bean的方式. 使用类构造器实例化. <be ...
- Dreamoon and MRT
Dreamoon and MRT 题目链接: http://codeforces.com/group/gRkn7bDfsN/contest/212299/problem/B 只需要考虑相对位置,设a0 ...
- activitymq 集群构建
测试zk是否正常 [root@node2 bin]# cd /zk/1/zookeeper-3.4.10/bin/ [root@node2 bin]# ./zkCli.sh -server 10.50 ...
- 关于MessageBox返回值
风格设置MB_OK. 此时无论点击确定还是点击X,都返回IDOK.风格设置MB_OKCANCEL,点击确认返回IDOK,点击取消和X都返回IDCANCEL.风格设置MB_YESNO,点击是返回IDYE ...
- github 从一个仓库换到另一个仓库
1.找到.git目录 2.打开config文件 3.修改仓库地址 4.重新提交 git push --all origin 这样就替我们的项目换仓啦!!!^_^
- 【2019.6.2】python:json操作、函数、集合、random()等
一.json操作: json就是一个字符串,从文件中读取json,必须是json格式.j'son串中必须是双引号,不能有单引号,单引号不能转换 1.1使用: import json #使用json先引 ...
- 条款34:区分接口继承和实现继承(Different between inheritance of interface and inheritance of implemenation)
NOTE: 1.接口继承和实现继承不同.在public继承之下,derived classes总是继承base class的接口. 2.pure virtual 函数只具体指定接口继承及缺省实现继承. ...
- 【C#】【数据结构】006-栈:链栈
C#数据结构:链栈 1.自定义链栈结构: 链栈节点类 using System.Collections; using System.Collections.Generic; using UnityEn ...
- u-boot-2012.04.01移植笔记——支持NAND启动
1.加入nand读写函数文件: 对于nand的读写我们需要特定的函数,之前写最小bootloader的时候曾写过nand.c文件,我们需要用到它.为了避免混淆,我们先将其改名为init.c,然后拷贝到 ...
- [图文教程] 使用Git 提交项目到码云
目录 1. 环境准备 2. 开发工具配置Git和SSH 3. 配置SSH到码云 4. 创建一个项目 5. Clone项目到本地 6. Push项目到码云 1. 环境准备 1.1 本机配置Git Hom ...