拷贝构造与拷贝赋值(C++)

2.8 拷贝构造与拷贝赋值

2.8.1 深拷贝与浅拷贝

#include <iostream>
using namespace std;

class Integer{
public:
	int *m_pa;

	Integer(int a = 0) {//构造函数
		m_pa = new int(a);
	}
	~Integer(void) {//析构函数
		delete m_pa;
	}
	void print(void) {
		cout << *m_pa << endl;
	}
};
int main(void){
	Integer i1(100);

	Integer i2(i1);//调用拷贝构造函数
	i2.print();
	return 0;
}

以上程序执行会出现double free的情况,为什么?

./a.out			#运行程序
100
*** Error in `./a.out': double free or corruption (fasttop): 0x085ba008 ***
Aborted (core dumped)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**浅拷贝:**类中的缺省拷贝构造函数,对指针形式的成员变量按字节复制,而不会复制指针所指向的内容,这种拷贝方式被称为浅拷贝。

**深拷贝:**为了避免浅拷贝的问题,获得完整意义上的对象副本,必须自己定义拷贝构造函数,针对指针指向的成员变量,实现对指针指向内容的复制,即深拷贝。

#include <iostream>
using namespace std;

class Integer{
public:
	int *m_pa;

	Integer(int a = 0) {
		m_pa = new int(a);
	}
	~Integer(void) { //析构造函数
		delete m_pa;
	}
	Integer(const Integer &that) { //自定义拷贝构造函数  可以解决浅拷贝的问题
		m_pa = new int(*that.m_pa);
	}
	void print(void) {
		cout << *m_pa << endl;
	}
};
int main(void){
	Integer i1(100);

	Integer i2(i1);//拷贝构造函数
	i2.print();
	return 0;
}

2.8.2 拷贝赋值

#include <iostream>
using namespace std;

class Integer{
public:
	int *m_pa;

	Integer(int a = 0) {
		m_pa = new int(a);
	}
	~Integer(void) { //析构造函数
		delete m_pa;
	}
	Integer(const Integer &that) { //自定义拷贝构造函数  可以解决浅拷贝的问题
		m_pa = new int(*that.m_pa);
	}
	void print(void) {
		cout << *m_pa << endl;
	}
};
int main(void){
	Integer i1(100);

	Integer i2(i1);//拷贝析构造函数
	i2.print();
    
    i2 = i1; //编译会出现  "double free" 的错误
	return 0;
}

当两个对象进行赋值操作时,比如 “i2 = i1” 编译器会将其处理为 “i2.operator = (i1) 的成员函数调用形式”,其中 “operator =” 称为拷贝赋值操作符函数,由该函数完成赋值运算,其返回结果就是表达的结果。

如果没有自己定义拷贝赋值操作符函数,编译器会为该类提供缺省的拷贝赋值操作符函数,用于完成两个对象的赋值操作。

但是编译器提供的缺省拷贝赋值函数,和缺省拷贝构造函数类似,也是浅拷贝,由 “ double free” 和 “ 内存泄漏” 的问题,这时需要自定义深拷贝赋值函数

#include <iostream>
using namespace std;

class Integer{
public:
	int *m_pa;

	Integer(int a) {
		m_pa = new int(a);
	}
	~Integer(void){
		delete m_pa;
	}
	Integer(const Integer &that) {
		m_pa = new int(*that.m_pa);
	}
	Integer &operator = (const Integer &that) {//拷贝赋值操作函数
		cout << "operator = " << endl;
		if(this != &that){ //判断是否自身赋值给自身
			delete m_pa;
			m_pa = new int(*that.m_pa);
		}
        return *this; //这个返回值的作用,可以在调用的时候 形成链式调用如:i2 = i1 = i1;
	}
	void print(void) {
		cout << *m_pa << endl;
	}
};
int main(void) {

	Integer i1(100);
	Integer i2 = i1;
	i2.print();

	i2 = i1;  //赋值操作
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值