构造函数调用规则:
构造函数按参数分类可以分为有参构造和无参构造,按类型分类可以分为普通构造和拷贝构造。
默认情况下,C++编译至少给一个类添加3个函数
默认构造函数(无参,函数体为空)
默认析构函数(无参,函数体为空)
默认拷贝构造函数,对属性进行值传递
构造函数调用规则如下:
如果用户定义有参构造函数,C++不在提供默认无参构造,但是会提供拷贝构造
如果用户定义拷贝构造函故,C++不会再提供其他构造函数
(编译器不会提供意味着必须要自己写,不写就用不了。编译器提供意味着自己不写也可以用)
析构函数的作用:
1 class Person 2 { 3 public: 4 Person() 5 { 6 cout << "Person的默认构造函数调用" << endl; 7 } 8 Person(int age,int height) 9 { 10 cout << "Person的有参构造函数调用" << endl; 11 m_Age = age; 12 m_Height = new int(height); 13 } 14 ~Person() 15 { 16 //析构代码,将堆区开辟数据做释放操作 17 if (m_Height != NULL) 18 { 19 delete m_Height; 20 m_Height = NULL; 21 cout << "Person的析构函数调用" << endl; 22 } 23 } 24 int m_Age; 25 int* m_Height; 26 };
浅拷贝和深拷贝:
如果利用编译器提供的拷贝构造函数,就会做浅拷贝操作。
浅拷贝出现问题在于:对象中成员属性具有指针类型,并且该指针指向一块堆区的内存,这样在做拷贝构造时,当调用两个析构函数的时候就会造成堆区的内存重复释放。
也就是说P2会把P1所有内容原封不动的拷贝过来,当P2析构时释放掉m_Height所指向的堆区内存时后P1再来释放这块内存就会非法操作。

1 class Person 2 { 3 public: 4 Person() 5 { 6 cout << "Person的默认构造函数调用" << endl; 7 } 8 Person(int age,int height) 9 { 10 cout << "Person的有参构造函数调用" << endl; 11 m_Age = age; 12 m_Height = new int(height); 13 } 14 //Person(const Person& p) 15 //{ 16 // m_Age = p.m_Age; 17 // cout << "Person的拷贝构造函数调用" << endl; 18 //} 19 ~Person() 20 { 21 //析构代码,将堆区开辟数据做释放操作 22 if (m_Height != NULL) 23 { 24 delete m_Height; 25 m_Height = NULL; 26 cout << "Person的析构函数调用" << endl; 27 } 28 } 29 int m_Age; 30 int* m_Height; 31 }; 32 void test01() 33 { 34 Person p(18,168); 35 Person p2(p); 36 cout << "p的年龄为:" << p.m_Age << "身高为:" << *p.m_Height << endl; 37 cout << "p2的年龄为:" << p2.m_Age << "身高为:" << *p2.m_Height << endl; 38 } 39 int main() 40 { 41 test01(); 42 }
解决方法是进行深拷贝,重新申请一块堆区内存,让P2中的指针指向这块堆区内存。

1 class Person 2 { 3 public: 4 Person() 5 { 6 cout << "Person的默认构造函数调用" << endl; 7 } 8 Person(int age,int height) 9 { 10 cout << "Person的有参构造函数调用" << endl; 11 m_Age = age; 12 m_Height = new int(height); 13 } 14 Person(const Person& p) 15 { 16 cout << "Person的拷贝构造函数调用" << endl; 17 m_Age = p.m_Age; 18 //当我们把拷贝构造函数注释掉的时候,编译器会自动进行以下程序,也就是说只要涉及到拷贝对象拷贝给被拷贝对象指针类型的成员函数的时候就是浅拷贝 19 //m_Height = p.m_Height; 20 //深拷贝操作 21 m_Height = new int(*p.m_Height); 22 } 23 ~Person() 24 { 25 //析构代码,将堆区开辟数据做释放操作 26 if (m_Height != NULL) 27 { 28 delete m_Height; 29 m_Height = NULL; 30 cout << "Person的析构函数调用" << endl; 31 } 32 } 33 int m_Age; 34 int* m_Height; 35 }; 36 void test01() 37 { 38 Person p(18,168); 39 Person p2(p); 40 cout << "p的年龄为:" << p.m_Age << "身高为:" << *p.m_Height << endl; 41 cout << "p2的年龄为:" << p2.m_Age << "身高为:" << *p2.m_Height << endl; 42 } 43 int main() 44 { 45 test01(); 46 }
















