类和对象_对象的初始化和清理(中)
构造函数调用规则
默认情况下,C++编译器至少给一个类添加3个函数
- 默认构造函数(无参,函数体为空)
- 默认析构函数(无参,函数体为空
- 默认拷贝构造函数,对属性进行值拷贝
构造函数调用的规则如下:
- 如果用户定义 有参构造函数,C++不再提供默认构造函数,但是会提供默认拷贝构造
- 如果用户定义 拷贝构造函数,C++不再提供其他构造函数
深拷贝与浅拷贝
深拷贝与浅拷贝是面试经典问题,也是常见的一个坑
浅拷贝:简单的赋值拷贝操作 (编译器提供的拷贝构造函数)
深拷贝:在堆区重新申请空间,进行拷贝操作
浅拷贝带来的问题:堆区内存重复释放
浅拷贝的问题利用深拷贝来解决(自己写拷贝构造函数)

#include <iostream> using namespace std; class Person { public: Person() { cout << "默认构造函数调用" << endl; } Person(int age, int height) { m_Age = age; m_Height = new int(height); //返回的是地址 //堆区开辟的数据手动开辟手动释放 //height需要在析构函数中释放 cout << "有参构造函数调用" << endl; } Person(const Person &p) { m_Age = p.m_Age; //m_Height = p.m_Height; 这是编译器默认的拷贝操作 //深拷贝操作 m_Height = new int(*p.m_Height); cout << "拷贝构造函数调用" << endl; } ~Person() { //将堆区开辟的数据做释放操作 if (m_Height != NULL) { delete m_Height; m_Height = NULL; //防止野指针出现 做置空操作 } cout << "析构函数调用" << endl; } int m_Age; int * m_Height; //身高 用指针是因为要开辟到堆区 }; void test01() { Person p1(18, 160); Person p2(p1); } int main() { test01(); }
总结:如果属性有在堆区开辟的,一定要自己提供拷贝构造函数,防止浅拷贝带来的问题
初始化列表
作用:
C++提供了初始化列表,用来初始化属性
语法: 构造函数(): 属性1(值1), 属性2(值2) ... {}
#include <iostream> using namespace std; class Person { public: //传统初始化操作 // Person(int a, int b, int c) { // m_A = a; // m_B = b; // m_C = c; // } //初始化列表 Person(int a, int b, int c):m_A(a), m_B(b), m_C(c) { } int m_A; int m_B; int m_C; }; int main() { Person p(10, 20, 30); cout << "m_A = " << p.m_A << endl; cout << "m_B = " << p.m_B << endl; cout << "m_C = " << p.m_C << endl; }

浙公网安备 33010602011771号