C++中对C的扩展学习新增内容———面向对象(继承)继承中对象的构造和析构
继承中对象的构造和析构
1、编译器会按照子类和父类大小分配内存。
2、先调用父类构造函数、再调用子类构造函数。
3、析构函数调用顺序和构造函数调用顺序相反。
代码验证:
// 1. 继承中对象的构造和析构 class Base { public: Base(int) { cout << "Base 的构造函数" << endl; m_a = 100; m_b = 200; } ~Base() { cout << "Base 析构函数" << endl; } public: int m_a; int m_b; }; class Derived : public Base { public: Derived() : Base(10) { cout << "Derived 构造函数" << endl; m_c = 300; } Derived(int) : Base(10) { cout << "Derived 构造函数" << endl; m_c = 300; } ~Derived() { cout << "Derived 析构函数" << endl; } public: int m_c; }; void test01() { Derived d; }
运行结果
2、初始化列表在继承中的作用
1、子类初始化的时候,编译器默认调用父类无参构造函数。
2、如果父类没有无惨构造函数,则需要使用初始化列表指定父类调用哪个构造函数。
3、如果父类没有无惨构造函数,那么子类所有的构造函数都必须要写初始化列表
3、继承中同名成员处理
1、如果子类中存在和父类同名的成员,父类的同名成员会被隐藏。
2、父类的数据只是隐藏,没有删除,所以依然可以使用类名作用域来访问父类成员。
class Base { public: Base() { m_num = 100; } void print() { cout << m_num << endl; } public: int m_num; static int s_num; }; int Base::s_num = 300; class Derived : public Base { public: Derived() { m_num = 666; } void print() { cout << m_num << endl; } public: int m_num; static int s_num; }; int Derived::s_num = 888; void test() { Derived d; // 1. 默认调用子类同名成员 d.print(); cout << d.m_num << " " << d.s_num << endl; // 2. 父类的数据只是隐藏,没有删除。所以仍然可以访问。 cout << d.Base::m_num << " " << d.Base::s_num << endl; }