C++中的深拷贝与浅拷贝
首先来介绍一下深拷贝和浅拷贝的概念
一.浅拷贝
浅拷贝:如果用默认的拷贝构造函数(赋值函数)去赋值有指针类型的成员变量的对象,将会使两个对象
的指针地址也是一样的,也就是说这两个对象的指针成员变量指向的是相同的地址。
如果程序中没有写拷贝构造函数,则会去调用默认构造函数,这个属于浅拷贝,是单纯的赋值关系,是将数据逐个的复制给拷贝的对象,
指向的是同一块内存,很容易造成堆区的内存重复释放的问题,深拷贝则是来解决这一问题的。
二.深拷贝
深拷贝:每个对象拥有自己的资源,此时需要显示提供拷贝构造函数和赋值函数。
拷贝构造函数的格式
Person(const Person& p) //Person是一个类
{
cout <<"Person的拷贝构造函数" << endl;
}
下面用程序来解释一下
首先用浅拷贝
1 #include<iostream> 2 3 using namespace std; 4 5 class Person 6 { 7 public: 8 9 Person(int age ,int height) 10 { 11 m_age = age; 12 m_height = new int(height); 13 cout << "Person的构造函" << endl; 14 } 15 16 // Person(const Person& p) 17 // { 18 // cout << "拷贝构造函数" << endl; 19 // m_age = p.m_age; 20 // m_height = new int(*p.m_height); 21 // } 22 23 ~Person() 24 { 25 if(m_height != NULL) 26 { 27 delete m_height; 28 m_height = NULL; 29 } 30 cout << "Person的析构函数" << endl; 31 } 32 33 int m_age; 34 int *m_height; 35 }; 36 37 void test1() 38 { 39 Person p1(18 , 160); 40 cout << "年龄:" << p1.m_age << "身高:" << *p1.m_height << endl; 41 Person p2(p1); 42 cout << "年龄" << p2.m_age << "身高:" << *p2.m_height << endl; 43 } 44 45 int main(int argc , char **argv) 46 { 47 test1(); 48 return 0; 49 }
利用的是默认拷贝构造,所以称为浅拷贝,我们就会发现一个问题,调用完对象之后,进行析构的时候发现堆区的内存被释放了两次,重复释放了
这就造成了程序出错,需要用深拷贝去解决浅拷贝的问题。
深拷贝
1 #include<iostream> 2 3 using namespace std; 4 5 class Person 6 { 7 public: 8 9 Person(int age ,int height) 10 { 11 m_age = age; 12 m_height = new int(height); 13 cout << "Person的构造函" << endl; 14 } 15 16 Person(const Person& p) 17 { 18 cout << "拷贝构造函数" << endl; 19 m_age = p.m_age; 20 m_height = new int(*p.m_height); 21 } 22 23 ~Person() 24 { 25 if(m_height != NULL) 26 { 27 delete m_height; 28 m_height = NULL; 29 } 30 cout << "Person的析构函数" << endl; 31 } 32 33 int m_age; 34 int *m_height; 35 }; 36 37 void test1() 38 { 39 Person p1(18 , 160); 40 cout << "年龄:" << p1.m_age << "身高:" << *p1.m_height << endl; 41 Person p2(p1); 42 cout << "年龄" << p2.m_age << "身高:" << *p2.m_height << endl; 43 } 44 45 int main(int argc , char **argv) 46 { 47 test1(); 48 return 0; 49 }
加入了拷贝构造函数,在进行拷贝的时候,在堆区各自分配了内存,防止了浅拷贝内存重复释放的问题。
上面就很好的解释了深拷贝和浅拷贝的应用和理解。