• 派生类构造函数顺序


    函数执行顺序

    构造函数执行顺序:

    1. 虚基类构造函数
    2. 普通基类构造函数
    3. 成员变量构造函数

    析构函数执行顺序:

    与构造函数相反顺序

    
    #include "iostream"
    
    using namespace std;
    
    class base
    {
    public:
        base() { cerr << __PRETTY_FUNCTION__ << endl; }
        ~base() { cerr << __PRETTY_FUNCTION__ << endl; }
        void fun() { cerr << __PRETTY_FUNCTION__ << endl; }
    };
    
    class base1
    {
    public:
        base1() { cerr << __PRETTY_FUNCTION__ << endl; }
        ~base1() { cerr << __PRETTY_FUNCTION__ << endl; }
        void fun() { cerr << __PRETTY_FUNCTION__ << endl; }
    };
    
    class vbase
    {
    public:
        vbase() { cerr << __PRETTY_FUNCTION__ << endl; }
        ~vbase() { cerr << __PRETTY_FUNCTION__ << endl; }
        void fun() { cerr << __PRETTY_FUNCTION__ << endl; }
    };
    
    class drive : public base, virtual public vbase, public base1
    {
    public:
        drive() { cerr << __PRETTY_FUNCTION__ << endl; }
        ~drive() { cerr << __PRETTY_FUNCTION__ << endl; }
        void fun() { cerr << __PRETTY_FUNCTION__ << endl; }
    };
    
    int main()
    {
        drive d;
    }
    

    虚继承

    基类可以是虚基类(添加virtual 继承),虚基类的作用在菱形继承情况下能发挥作用。
    例如:

    // 基类:
    class A { public: void func(){}}
    
    // 单继承:
    class B1: public A { public: }
    class B2: public A { public: }
    
    // 普通多继承:
    class D: public B1, public B2 { public: }
    

    如上:类 D 继承了 B1 与 B2,而二者都从基类 A 派生出来,所以 A,B 都继承了成员函数 func(),这时候就会存在下图(b)的情况,如果为虚继承则是(a)的情况。
    普通多继承就会存在一个问题,在 D 中不能直接调用 func 函数,因为会发生歧义,到底是调用 B1 还是B2 中的函数。而虚继承则解决了这个问题。
    虚继承解决的原理可以理解为“编译器延迟对虚基类的初始化,直到继承的末尾才初始化”,也就是由最后一个类,在本例就是 D 里来初始化 A(基于这个原理思考下,怎么利用虚继承实现不可继承的类)

    测试代码:

    #include "iostream"
    
    using namespace std;
    
    class base
    {
    public:
        base() { cerr << __PRETTY_FUNCTION__ << endl; }
        ~base() { cerr << __PRETTY_FUNCTION__ << endl; }
        void fun() { cerr << __PRETTY_FUNCTION__ << endl; }
    };
    
    class base1 : virtual public base
    {
    public:
        base1() { cerr << __PRETTY_FUNCTION__ << endl; }
        ~base1() { cerr << __PRETTY_FUNCTION__ << endl; }
    };
    
    class base2 : virtual public base
    {
    public:
        base2() { cerr << __PRETTY_FUNCTION__ << endl; }
        ~base2() { cerr << __PRETTY_FUNCTION__ << endl; }
    };
    
    class drive : public base1, public base2
    {
    public:
        drive() { cerr << __PRETTY_FUNCTION__ << endl; }
        ~drive() { cerr << __PRETTY_FUNCTION__ << endl; }
    };
    
    int main(int argc, char *argv[])
    {
        drive d;
    
        d.fun();
    
        return 0;
    }
    

  • 相关阅读:
    大话测试数据(一)
    两个小案例
    关于那些难改的bug
    关于测试人员的职业发展
    python中的模块
    python为什么会有@classmethod?
    Javascript oop深入学习笔记(三)--javascript中类的实现
    NODE编程(一)--Node功能的组织和重用
    javascript oop深入学习笔记(二)--javascript的函数
    javascript oop深入学习笔记(一)
  • 原文地址:https://www.cnblogs.com/sinpo828/p/10678968.html
Copyright © 2020-2023  润新知