我的主题是。每天积累一点点。

===========================================

在类定义中,假设没有提供自己的拷贝构造函数,则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】深拷贝和浅拷贝的更多相关文章

  1. Java基础(十三)--深拷贝和浅拷贝

    在上篇文章:Java基础(十二)--clone()方法,我们简单介绍了clone()的使用 clone()对于基本数据类型的拷贝是完全没问题的,但是如果是引用数据类型呢? @Data @NoArgsC ...

  2. JavaScript基础之--- 深拷贝与浅拷贝

    理解深拷贝和浅拷贝之前,先来看一下JavaScript的数据类型. 1.基本类型和引用类型 //案例1 var num1 = 1, num2 = num1; console.log(num1) con ...

  3. .NET基础知识之八——深拷贝,浅拷贝

    目录 1.概念 2.使用赋值符号"=" 3.浅复制 4.深复制 5.问题一:如果类里面嵌套有多个类,然后嵌套类里面又嵌套类,那么像上面实现深拷贝的方法还能用吗? 6.问题二:实现深 ...

  4. Python基础-字符串、集合类型、判断、深拷贝与浅拷贝、文件读写

    字符串 1.定义三个变量: 2.交换两个变量值 1)引入第三个变量: 2)Python引入第三方变量: 3)不引入第三方变量: 3. isalpha 是否是汉字或字母 4.Isalnum  是否是汉字 ...

  5. C++基础-4-封装(构造函数与析构函数,深拷贝与浅拷贝,静态成员,this,友元,const修饰成员函数)

    4. 封装 4.1.1 封装的意义 1 #include<iostream> 2 #include<string> 3 using namespace std; 4 5 con ...

  6. JavaScript中面向对象的的深拷贝和浅拷贝

    理解深拷贝和浅拷贝之前需要弄懂一些基础概念,内存中存储的变量类型分为值类型和引用类型. 1.值类型赋值的存储特点, 将变量内的数据全部拷贝一份, 存储给新的变量. 例如:var num = 123 : ...

  7. 也来玩玩 javascript对象深拷贝,浅拷贝

    经常看到讨论c#深拷贝,浅拷贝的博客,最近js写的比较多, 所以也来玩玩js的对象拷贝. 下面是维基百科对深浅拷贝的解释: 浅拷贝 One method of copying an object is ...

  8. 设计模式_11_原型模式(prototype)深拷贝、浅拷贝

    设计模式_11_原型模式(prototype) 浅拷贝: package designPatternOf23; /** * 定义:用原型实例,指定创建对象的种类,并通过拷贝这些原型创建新的对象 * P ...

  9. 浅析C#深拷贝与浅拷贝

    1.深拷贝与浅拷贝   拷贝即是通常所说的复制(Copy)或克隆(Clone),对象的拷贝也就是从现有对象复制一个“一模一样”的新对象出来.虽然都是复制对象,但是不同的 复制方法,复制出来的新对象却并 ...

  10. 浅析C#深拷贝与浅拷贝(转)

    1.深拷贝与浅拷贝   拷贝即是通常所说的复制(Copy)或克隆(Clone),对象的拷贝也就是从现有对象复制一个“一模一样”的新对象出来.虽然都是复制对象,但是不同的 复制方法,复制出来的新对象却并 ...

随机推荐

  1. react开启一个项目 webpack版本出错

    npx create-react-app my-app cd my-app npm start 在命令行里执行以上语句就可(前两天刚刚发现,最新版的react对webpack的版本要了新要求,大概是他 ...

  2. 使用plsql导入dmp文件缺少imp*.exe

    在C:\app\Administrator\product\11.2.0\client_2\BIN 找到imp.exe 导入

  3. 下载GitHub上的dnSpy源码

    一.方法 下载GitHub上项目的方法,目前我知道的有四种: 1.用svn软件checkout下载 2.安装git,然后git命令下载 3.直接下载项目压缩包 4.安装GitHub的客户端,然后下载项 ...

  4. TWaver可视化编辑器的前世今生(一)电信网管编辑器

    走到今天,TWaver,一个致力于在技术领域(Technology)的弄潮儿(Waver),已经是第十二个年头.当年网吧的小网管都是IDC机房的运维人员了,TWaver也见证了这个时代的成长变迁. 萌 ...

  5. java中HashMap,LinkedHashMap,TreeMap,HashTable的区别

    java为数据结构中的映射定义了一个接口java.util.Map;它有四个实现类,分别是HashMap Hashtable LinkedHashMap 和TreeMap Map主要用于存储健值对,根 ...

  6. Sqlserver添加加字段、删除字段、修改字段类型、修改字段名、修改字段默认值

    参考:https://www.cnblogs.com/pangpanghuan/p/6432331.html 初始化表: --.添加字段 --1.1.为null alter table DataTab ...

  7. 16. PLUGINS

    16. PLUGINS PLUGINS表提供有关服务器插件的信息. PLUGINS表有以下列: PLUGIN_NAME :用于在诸如INSTALL PLUGIN和UNINSTALL PLUGIN之类的 ...

  8. vue项目中设置跨域

    config->index.js 'use strict' // Template version: 1.3.1 // see http://vuejs-templates.github.io/ ...

  9. tensorflow with gpu 环境配置

    1.准备工作 1.1 确保GPU驱动已经安装 lspci | grep -i nvidia 通过此命令可以查看GPU信息,测试机已经安装GPU驱动

  10. 让你系统的了解shell

    当你在进行登录时,系统会检查的文档:1. /etc/profile:首先,系统会检查这个文件,以定义如下这些变量:PATH.USER.LOGNAME.MAIL.HOSTNAME.HISTSIZE.IN ...