【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

可以看到,第二次释放资源的时候,出错了。因为默认拷贝构造函数并没有分配新的资源。

所以我们需要自定义拷贝构造函数,并分配资源,使拷贝和被拷贝的对象指向不同的资源,这就是深拷贝的概念。

具体如下:

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】深拷贝和浅拷贝,布布扣,bubuko.com

时间: 2024-07-29 01:30:51

【C++基础 02】深拷贝和浅拷贝的相关文章

【转】 c++拷贝构造函数(深拷贝,浅拷贝)详解

c++拷贝构造函数(深拷贝,浅拷贝)详解 2013-11-05 20:30:29 分类: C/C++ 原文地址:http://blog.chinaunix.net/uid-28977986-id-3977861.html 一.什么是拷贝构造函数      首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: int a=100; int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.  下面看一个类对象拷贝的简单例子. #include<iostream

c++拷贝构造函数(深拷贝,浅拷贝)详解

一.什么是拷贝构造函数      首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: int a=100; int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.  下面看一个类对象拷贝的简单例子. #include<iostream> using namespace std; class CExample { private: int a; public: //构造函数 CExample(int b) { a=b; printf("con

oc中深拷贝与浅拷贝

shallow 浅拷贝       Deep深拷贝 1.产生一个新对象,对象的内容与源对象相同 2.源对象与新对象使用不同的内存区域 3.需要NSCopying 或者NSMutableCopying协议才能使用复制功能 ? 4.Fundation中得基础数据类型如Nsstring.NSNumber 等都实现了NSCopying 5.新对象的引用计数为1 6.copy与mutableCopy的区别 copy返回不可变对象(包括可变对象在内) ? mutableCopy返回可变对象 7.浅拷贝只复制

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

理解深拷贝和浅拷贝之前需要弄懂一些基础概念,内存中存储的变量类型分为值类型和引用类型. 1.值类型赋值的存储特点, 将变量内的数据全部拷贝一份, 存储给新的变量. 例如:var num = 123 :var num1=num; 表示变量中存储的数字是 123.然后将数据拷贝一份,就是将 123 拷贝一份. 那么内存中有 2 个 数组;将拷贝数据赋值给 num2,其特点是在内存中有两个数据副本.这可以理解为浅拷贝. 2.引用类型的赋值. var o={name:'张三‘}: var obj=o;

字典的深拷贝与浅拷贝

以前只知道用dict2 = dict1 来进行复制(备份),结果发现对dict2做增删改等操作时,dict1也会随之变化,反过来也这样.没有好好学习基础的我,自然在这里面吃了不少的亏... 下面我们来介绍一下python的深拷贝与浅拷贝: 1 #!/usr/bin/python 2 # -*- coding: UTF-8 -*- 3 4 dict1 = {'user':'runoob','num':[1,2,3]} 5 6 dict2 = dict1 # 浅拷贝: 引用对象 7 dict3 =

(转载)深拷贝与浅拷贝

1.深拷贝与浅拷贝 拷贝即是通常所说的复制(Copy)或克隆(Clone),对象的拷贝也就是从现有对象复制一个"一模一样"的新对象出来.虽然都是复制对象,但是不同的复制方法,复制出来的新对象却并非完全一模一样,对象内部存在着一些差异.通常的拷贝方法有两种,即深拷贝和浅拷贝,那二者之间有何区别呢?MSDN里对 IClone接口的Clone方法有这样的说明:在深层副本中,所有的对象都是重复的:而在浅表副本中,只有顶级对象是重复的,并且顶级以下的对象包含引用.可以看出,深拷贝和浅拷贝之间的区

浅析C#深拷贝与浅拷贝

1.深拷贝与浅拷贝 拷贝即是通常所说的复制(Copy)或克隆(Clone),对象的拷贝也就是从现有对象复制一个“一模一样”的新对象出来.虽然都是复制对象,但是不同的 复制方法,复制出来的新对象却并非完全一模一样,对象内部存在着一些差异.通常的拷贝方法有两种,即深拷贝和浅拷贝,那二者之间有何区别呢?MSDN里对 IClone接口的Clone方法有这样的说明:在深层副本中,所有的对象都是重复的:而在浅表副本中,只有顶级对象是重复的,并且顶级以下的对象包含引 用.可以看出,深拷贝和浅拷贝之间的区别在于

从String类中看C++当中的深拷贝与浅拷贝解

了解过C++语言的人,都应该知道,C++语言中的构造函数,析构函数,拷贝构造函数,赋值运算符重载函数,如果不定义,编译器会自动生成的,当然,生成的只是一些最基本的,在达不到我们要求的条件下,就需要我们自己重新定义这些函数. 我们现在说的讲的是深拷贝与浅拷贝,当然讨论这个问题的基础,一般情况下是我们定义的变量是以指针形式出现的,原因就在于,不论赋值还是拷贝,我们要实现两个指针指向的内容一致,那我得到新的指针和原指针是指向同一块内存空间还是两块内存空间的相同内容.如果是指向同一块空间,就存在了安全隐

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

1.深拷贝与浅拷贝 拷贝即是通常所说的复制(Copy)或克隆(Clone),对象的拷贝也就是从现有对象复制一个“一模一样”的新对象出来.虽然都是复制对象,但是不同的 复制方法,复制出来的新对象却并非完全一模一样,对象内部存在着一些差异.通常的拷贝方法有两种,即深拷贝和浅拷贝,那二者之间有何区别呢?MSDN里对 IClone接口的Clone方法有这样的说明:在深层副本中,所有的对象都是重复的:而在浅表副本中,只有顶级对象是重复的,并且顶级以下的对象包含引 用.可以看出,深拷贝和浅拷贝之间的区别在于