浅拷贝:单纯的赋值拷贝操作
一般来说,编译器自带的复制构造函数都为浅拷贝函数,由于只是执行一个值传递指令,因此两个或多个对象最终指向的是同一个内存空间,从而在释放内存时带来错误
深拷贝:在堆区重新申请空间进行拷贝操作
使用new关键字重新再堆区开辟新的内存拷贝变量并储存在新的空间,因此会有两个地址
案例:
#include<iostream>
using namespace std;
class Person{
public:
Person(){
cout<<"Person 默认构造函数调用"<<endl;
}
Person(int age, int height){
m_Height = new int(height);
age = m_Age;
cout<<"Person 有参构造函数调用"<<endl;
}
~Person() //析构的作用之一就是如下的将内存释放的过程
{
if(m_Height != NULL_{
delete m_Height;
m_Height = NULL;
}
cout<<"Person 析构函数调用"<<endl;
int m_Age;
int *m_Height;
};
void Example(){
Person p1(18, 160);
cout<<"p1的年龄为"<<p1.m_Age<<"身高为"<<*p1.m_Height<<endl;
Person p2(p1);
cout<<"p2的年龄为"<<p2.m_Age<<"身高为"<<*p2.m_Height<<endl;
}
int main(){
Example;
return 0;
}
以上程序在编译运行当中会报错,因为如果使用编译器自带的复制构造函数,就会带来浅拷贝的问题,如果在析构函数中释放内存就会导致重复释放发生错误。使用深拷贝就会在另外一个变量保存时使用新的地址,从而达到两个使用的内存不同,避免重复释放。
这时可以在析构函数上方添加如下代码:
Person(const Person &p){
cout<<"深拷贝"<<endl;
m_Age = p.m_Age;
m_Height = new int(*p.m_Height);//编译器的浅拷贝实现代码
//m_Height = p.m_Height;
}