C++浅拷贝与深拷贝

本文探讨了C++中浅拷贝和深拷贝的概念,通过示例代码展示了默认拷贝构造函数(浅拷贝)可能导致的问题及解决方法——自定义深拷贝构造函数。当类中涉及堆区资源时,不正确的拷贝构造函数可能导致内存泄漏或程序崩溃。正确实现深拷贝能确保每个对象独立管理自己的堆区资源,避免副作用。

浅拷贝:简单的赋值拷贝操作

深拷贝:在堆区重新申请空间,进行拷贝操作

        下面这段代码即为简单的浅拷贝操作,在程序员为定义拷贝构造函数的时候,编译器会调用默认的拷贝构造函数进行拷贝(默认的拷贝构造函数为浅拷贝,即不能对堆区的内容进行拷贝)

#include <iostream>
using namespace std;

class People
{
public:
	//无参构造函数
	People()
	{
		m_name = "";
		m_age = 0;
		cout << "无参构造" << endl;
	}
	//初始化列表
	People(string name, int age):m_name(name),m_age(age)
	{
		cout << "带参构造" << endl;
	}
	~People()
	{
		cout << "析构函数" << endl;
	}
	string ShowName()
	{
		return m_name;
	}
	int ShowAge()
	{
		return m_age;
	}

private:
	string m_name;
	int m_age;
};

void test1()
{
	People p1("pw", 21);
	cout << "name = " << p1.ShowName() << " age = " << p1.ShowAge() << endl;
	People p2(p1);
	cout << "name = " << p2.ShowName() << " age = " << p2.ShowAge() << endl;
}

int main(int argc, char *argv[])
{
	test1();

	return 0;
}

 这段代码就是简单的将p1的m_name以及m_age赋值给p2,并打印内容

运行结果:

        但是在创建构造函数的时候,申请了堆区资源,浅拷贝就会发生错误,需要自己定义一个拷贝函数,即深拷贝 

对深拷贝构造函数的实现:

#include <iostream>
using namespace std;

class People
{
public:
	//无参构造函数
	People()
	{
		m_name = "";
		m_age = 0;
		m_height = NULL;
		cout << "无参构造" << endl;
	}
	//初始化列表
	People(string name, int age, int height)
	{
		m_name = name;
		m_age = age;
		m_height = new int(height);    //申请资源,并赋值height
		cout << "带参构造" << endl;
	}
	~People()
	{
		delete m_height;   //关闭开辟的堆区空间
		m_height = NULL;
		cout << "析构函数" << endl;
	}
	string ShowName()
	{
		return m_name;
	}
	int ShowAge()
	{
		return m_age;
	}
	int ShowHeight()
	{
		return *m_height;
	}
#if 1
	People(const People &p)   //const防止修改内容
	{
		m_name = p.m_name;
		m_age = p.m_age;
		m_height = new int(*p.m_height);
		cout << "自己创建的拷贝构造函数" << endl;
	}
#endif

private:
	string m_name;
	int m_age;
	int *m_height;
};

void test1()
{
	People p1("pw", 21, 175);
	cout << "name = " << p1.ShowName() << " age = " << p1.ShowAge() << " height = " << p1.ShowHeight() << endl;
	People p2(p1);
	cout << "name = " << p2.ShowName() << " age = " << p2.ShowAge() << " height = " << p2.ShowHeight() << endl;
}

int main(int argc, char *argv[])
{
	test1();

	return 0;
}

如果使用编译器提供的拷贝构造函数(浅拷贝),运行结果为:

如果使用自己创建的拷贝构造函数(深拷贝),运行结果为: 

        出现这样的原因是因为,当我们没有定义拷贝构造函数时,会在拷贝对象时调用默认拷贝构造函数,进行浅拷贝,即对指针拷贝后会出现两个指针指向同一个内存空间,所以在释放资源的时候,会对同一片空间释放两次,从而导致程序崩溃,而我们自己定义的拷贝构造函数,是申请了两片堆区空间,p1、p2分别释放自己相对应的堆区空间,所以程序正常运行。

        总结:在定义一个类的时候,运用到了堆区空间,拷贝构造函数应该自己定义。 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值