拷贝构造函数(深拷贝vs浅拷贝)

类对象之间的初始化是由类的拷贝构造函数完成的。它是一种特殊的构造函数,它的作用是用一个已知的对象来初始化另一个对象。如果在类中没有显式地声明一个拷贝构造函数,那么,编译器将会自动生成一个默认的拷贝构造函数,该构造函数完成对象之间的位拷贝。位拷贝又称浅拷贝。

一、拷贝构造函数定义格式

类名::拷贝构造函数名(类名& 引用名)

例如:

Tdate ::Tdate(Tdate & d); //形参是一个对象的引用

CString( const CString & stringSrc ); //形参是一个const的对象引用

二、通常在下述三种情况下,需要用拷贝初始化构造函数:

1)明确表示由一个对象初始化另一个对象时;如Cdate day3(d1);

2)当对象作为函数实参传递给函数形参时;如fun(Cdate day);

3)当对象作为函数的返回值,创建一个临时对象时。

浅拷贝和深拷贝

浅拷贝只对对象数据成员进行简单的赋值复制操作,在某些状况下,类内成员变量需要动态开辟堆内存,如果实行位拷贝,也就是把对象里的值完全复制给另一个对象,如A=B。这时,如果B中有一个成员变量指针已经申请了内存,那A中的那个成员变量也指向同一块内存。这就出现了问题:当B把内存释放了(如:析构),这时A内的指针就是野指针了,出现运行错误。

深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝。下面举个深拷贝的例子。

#include "stdafx.h"
#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;
class CClass
{
public:
	CClass (char *cName="",int snum=0);
	~CClass()
	{cout<<"析构班级:"<<pname<<endl;
	delete  pname;
	}
	void Print();
private:
	char *pname;
	int num;
};

CClass::CClass(char *cName,int snum)
{
	int length = strlen(cName);
	pname = new char[length+1];
	if (pname!=0)         //pname!=NULL
	strcpy(pname,cName);
	num=snum;
	cout<<"创建班级:"<<pname<<endl;
}

void CClass::Print()
{
	cout<<pname<<"班的人数为:"<<num<<endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
	CClass c1("计算机061班,56);
	CClass c2 (c1);
	c1.Print();
	c2.Print();
	//system("pause");
	return 0;
}

c1、c2内存分配情况(深拷贝)

CClass(CClass &p);  //自定义拷贝构造函数声明
//添加自定义拷贝构造函数
CClass::CClass(CClass &p)
{
	pname = new char[strlen(p.pname )+1];
	if (pname!=0)
		strcpy(pname,p.pname);
	num=p.num ;
	cout<<"创建班级的拷贝:"<<pname<<endl;
}

运行结果:

创建班级:计算机061班

创建班级的拷贝:计算机061班

计算机061班班的人数为:56

计算机061班班的人数为:56

析构班级:计算机061班

析构班级:计算机061班

时间: 2024-10-14 06:25:39

拷贝构造函数(深拷贝vs浅拷贝)的相关文章

【转载】C++拷贝构造函数(深拷贝,浅拷贝)

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

【转】 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++拷贝构造函数(深拷贝,浅拷贝)

http://www.cnblogs.com/BlueTzar/articles/1223313.html 对于普通类型的对象来说,它们之间的复制是很简单的,例如:int a=88;int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.下面看一个类对象拷贝的简单例子. 1 #include <iostream> 2 using namespace std; 3 4 class CExample { 5 private: 6 int a; 7 public: 8

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

c++拷贝构造函数(深拷贝、浅拷贝)——转

拷贝构造函数: 拷贝构造函数是一种特殊的构造函数,函数的名称必须和类名称一致,它的唯一的一个参数是本类的一个引用变量,该参数是const类型,不可变的.例如:类A的拷贝构造函数的形式为A(A& x).当用一个已经初始化过了的自定义类类型对象去初始化另一个新构造的对象的时候,拷贝函数就会被自动调用.也就是说,当类的对象需要拷贝时,拷贝构造函数将会被调用.以下情况会自动调用拷贝构造函数: 1.一个对象以值传递的方式传入函数体 2.一个对象以值传递的方式从函数返回,如下: #include <io

C++ Primer笔记9_构造函数_拷贝构造(深拷贝与浅拷贝)

1.构造函数: >构造函数是一个特殊的.与类同名的成员函数,用于给每一个成员设置适当的初始值. >构造函数不能有返回值,函数名与类名同样. >缺省构造函数时,系统将自己主动调用该缺省构造函数初始化对象,缺省构造函数会将全部数据成员都初始化为零或       空.缺省构造函数是不带參数的构造函数. >创建一个对象时,系统自己主动调用构造函数. 构造函数的特点: 1.构造函数能够重载,传入什么实參决定调用不同版本号的构造函数. 2.构造函数不能声明为const .也不能声明为virtu

C++拷贝构造函数(深拷贝&amp;浅拷贝)

对于普通类型的对象来说,它们之间的复制是很简单的,例如: int a=88; int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.下面看一个类对象拷贝的简单例子. <iostream> using namespace std; class CExample { private:      int a; public:      CExample(int b)      { a=b;}      void Show ()      {         cout

构造函数-深拷贝与浅拷贝

1 #include<iostream> 2 #include<string> 3 using namespace std; 4 //构造函数(拷贝构造函数),析构函数, 5 /*深拷贝:是指编译器给类提供定默认拷贝构造函数拷贝含有指针成员对象时, 6 调用默认析构函数多次释放堆中同一块内存,导致内存访问异常. 7 8 解决办法:自定义拷贝构造函数,针对指针成员, 9 用new关键字开辟另一块堆内存,存放拷贝对象的指针成员. 10 */ 11 class Student 12 {

python的拷贝(深拷贝和浅拷贝)

今天看了几篇关于python拷贝的博文,感觉不太清楚,所以我就自己做实验试一下,特此记录. 拷贝是针对组合对象说的,比如列表,类等,而数字,字符串这样的变量是没有拷贝这一说的. 实现拷贝有: 1.工厂函数 2.切片操作 3.对象的copy方法 4.copy模块的copy方法 Notice:在python2.2之后将一些原来的内建函数和一些没有的内建函数转换成了工厂函数,而这些内建函数一些现在仍然有. 工厂函数虽然貌似函数,但它是一个类. 内建函数大概有这些(未详细考证): int(),long(