c++基础(六)——深拷贝与浅拷贝

一、深拷贝与浅拷贝

浅拷贝:简单的赋值拷贝操作
深拷贝:在堆栈区重新申请空间,进行拷贝操作

(一)、浅拷贝

(1)、浅拷贝应用

浅拷贝从定义上我们可以看出,这只是一个简单的赋值操作,也就是将堆区已经申请空间内的数值进行一个赋值,无需重新申请空间。具体样例如下:

class person_a
{
    
    
public:
	person_a()
	{
    
    
		cout << "这是一个默认构造函数" << endl;
	}

	person_a(int age)
	{
    
    	
		m_age = age;
		cout << "年龄是" << age << endl;
	}
	~person_a()
	{
    
    
		cout << "这是一个析构函数" << endl;
	}

	int m_age;

};

void test1()
{
    
    
	person_a p1(18);
	person_a p2(p1);
	
	cout << "p1的年龄为" << p1.m_age << endl;
	cout << "p2的年龄为" << p2.m_age << endl;
}

通过简单的括号赋值法将数值赋值给已经在栈区空间内的变量。

(二)、浅拷贝所带来的问题

class person_a
{
    
    
public:
	person_a()
	{
    
    
		cout << "这是一个默认构造函数" << endl;
	}

	person_a(int age, int weight)
	{
    
    	
		//将数据创建到堆区
		m_weight = new int(weight);
	}
	~person_a()
	{
    
    

		//将堆区开辟的数据做释放的操作
		if (m_weight != NULL)
		{
    
    
			delete m_weight;
			m_weight = NULL;
		}
		cout << "这是一个析构函数" << endl;
	}

	int *m_weight;
};

void test1()
{
    
    
	person_a p1(120);
	person_a p2(p1);
	
	cout << "身高为:"<< *p1.m_weight << endl;
	cout << "身高为:" << *p2.m_weight << endl;
}

当我们运行如上代码时,此时程序会报错:
在这里插入图片描述
对于以上的报错说明如下:
当使用new在堆区开辟一个内存空间时,是需要进行人为清除的,也就是通过析构函数中的内容。当我们通过浅拷贝来将对象p1中的内容拷贝到P2中时,也就将开辟堆区内存空间的地址复制到了p2中。按照内存操作先进后出的原则,当调用P2中的析构函数时,会将堆区新开辟的内存空间清理掉,而执行p1中的析构函数时,由于堆区内的空间已经被清理,则会报出如上的错误。

所以浅拷贝的弊端就是重复的释放堆区内存。
这种情况要怎么解决呢?
我们在复制一段数据的时候,我们可以在堆区内重新开辟一块内存开保存这块数据。这种方法我们称之为深拷贝。

(二)、深拷贝

深拷贝我们需要自己构造一个构造函数,其方法如下:

	//使用指针常量的方法,将数值固定,使指针可以指向指定位置
	person_a(const person_a &p)
	{
    
    
	
		cout << "拷贝构造函数调用" << endl;
		//编译器默认实现的是如下代码
		//m_weight = p.m_weight;
		//深拷贝的操作是:通过new在堆区内开辟一段新的内存空间,并且将数值存放于这一新的内存空间内。
		m_weight = new int(*p.m_weight);
	
	}

猜你喜欢

转载自blog.csdn.net/qq_52302919/article/details/126590957