C++类对象之间复制,拷贝构造函数的作用,深拷贝与浅拷贝

在C++ 中,当类对象之间相互赋值的时候会存在拷贝的问题。特别是在使用vector对类对象进行管理的时候,这个问题会比较明显。这个时候,定义类的拷贝构造函数就很有作用了。

先说说浅拷贝的情况,代码如下:

#include <iostream>
using namespace std;

class image
{
public:
	int *pImgdata;
	int width;
	int height;
	image(int w, int h);
	~image();
};
image::image(int w, int h)
{
	width = w;
	height = h;
	pImgdata = new int[w * h];
}

image::~image()
{
}

void main()
{
	image A(100, 100);
	cout << "A的地址是: " <<A.pImgdata << endl;
	image B = A;
	cout << "B的参数时: " << endl;
	cout << B.height << endl;
	cout << B.width << endl;
	cout << B.pImgdata << endl;

	delete[] B.pImgdata;
	delete[] A.pImgdata;

	cin.get();
}
          运行结果如下:

        

从运行结果可以看出,

当将对象A赋值给对象B的时候,采用的是直接赋值的方法,对象A的width和height参数成功赋值给对象B,同时对象B和A的指针的地址相同,地址也成功复制了。但是后面出错了,问题在于,对象A虽然将指针地址成功赋值给B,但是A与B的指针指向的是同一块新建的内存,即对象A的指针的那块内存。所以,程序中,执行语句 

  delete[ ] B.pImgdata;
的时候,表面上看是释放的对象B 的内存,实际释放的是对象A的内存,因为在对象的赋值过程中,并没有给对象B新开辟内存,仅仅是将A的指针地址赋值给了对象B,这样对象B与A的指针实际都指向的是A的指针所指向的那块内存。所以,当程序在执行语句:
delete[] A.pImgdata;
的时候,就相当于对同一块内存进行了二次释放。但是,用new开辟的内存,只能用delete释放一次,如果多次释放同一块new的内存则会出错。这就是程序问题的所在。

        这就是浅拷贝的情况,只是对对象中的相关参数的值进行了拷贝和复制,但是对相关更深入的,比如内存啥的,并没有复制。

        下面就上面出现的问题,结合类的拷贝构造函数说下深拷贝的情况。

        在上述的代码上为类添加了类的拷贝构造函数。主函数不变,修改后的类声明和拷贝构造函数的定义如下:

class image
{
public:
	int *pImgdata;
	int width;
	int height;
	image(int w, int h);
	image(const image& C);
	~image();
};
拷贝构造函数:

image::image(const image& C)
{
	width = C.width;
	height = C.height;
	pImgdata = new int[width * height];
}
在拷贝构造函数中,新开辟了内存。运行结果如下:

结果看出,对象A与B的指针的地址不同,最后两句释放内存的语句都能顺利运行,说明对象A与B的指针都有各自不用的内存块,所以才能两次分别释放内存。

关于拷贝构造函数的声明、定义和相关注意的格式问题:

拷贝构造函数是一种特殊的构造函数,函数没有返回值,函数名称和类名称一致,其唯一的一个参数必须是本类类型的一个引用变量,必须是引用类型,而且还是本类型的类对象,必须是const常量类型。比如本例程中的构造函数如下:

image(const image& C); //声明形式

//函数定义如下

image::image(const image& C)
{
	width = C.width;
	height = C.height;
	pImgdata = new int[width * height];
}

和一般的构造函数声明形式和定义差不多。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值