继承下构造函数与析构函数顺序及虚函数

经测试,继承下构造函数与析构函数顺序(包括虚析构函数),结果如下:

普通继承或虚函数继承,子类指针指向子类实例:

父类构造函数>>>子类构造函数
子类析构函数>>>父类析构函数

普通继承,父类指针指向子类实例:

父类构造函数>>>子类构造函数
父类析构函数

虚函数继承,父类指针指向子类实例:

父类构造函数>>>子类构造函数
子类析构函数>>>父类析构函数

由以上结果及测试情况得出以下结论:

1. 无论如何继承,指针如何指向,构造函数都以最终实例化为准,顺序始终是先父类后子类
2. 析构函数遵从类的多态性,非虚析构函数则以指针类型为准,虚析构函数则以最终实例为准,存在继承关系时顺序是先子类后父类
3. 虚析构函数与普通虚函数还是有不同的,普通虚函数仅按最终实例执行一次,而虚析构函数按最终实例执行后仍会依次向上逐个执行其父类析构函数
4. 可以通过"父类::函数名"来在子类中访问父类的函数,此时不论该函数是否虚函数,都会直接调用父类对应的函数

测试过程如下:

四个类的定义如下:

#include <iostream>

using namespace std;

class A
{
    public:
        A() { cout<<"A Constructor"<<endl; }
        ~A() { cout<<"A Destructor"<<endl; }
        void fun() { cout<<"A Function"<<endl; }
        void funA() { cout<<"A FunctionA"<<endl; }
};

class AA : public A
{
    public:
        AA() { cout<<"AA Constructor"<<endl; }
        ~AA() { cout<<"AA Destructor"<<endl; }
        void fun() { cout<<"AA Function"<<endl; }
        void funA() { cout<<"AA FunctionA"<<endl; A::fun(); A::funA(); }
};

class B
{
    public:
        B() { cout<<"B Constructor"<<endl; }
        virtual ~B() { cout<<"B Destructor"<<endl; }
        virtual void fun() { cout<<"B Function"<<endl; }
        virtual void funB() { cout<<"B FunctionB"<<endl; }
};

class BB : public B
{
    public:
        BB() { cout<<"BB Constructor"<<endl; }
        ~BB() { cout<<"BB Destructor"<<endl; }
        void fun() { cout<<"BB Function"<<endl; }
        void funB() { cout<<"BB Function"<<endl; B::fun(); B::funB(); }
};

测试不进行指针转换,子类指针指向子类实例测试代码:

/*-----------------------------------------------------------------------------
 *  测试普通继承下,构造函数与析构函数顺序
 *-----------------------------------------------------------------------------*/
void test1()
{
    A *a = NULL;
    AA *aa = NULL;
    B *b = NULL;
    BB *bb = NULL;

    aa = new AA();
    aa->fun();
    delete aa;
    cout<<"======================="<<endl;
    bb = new BB();
    bb->fun();
    delete bb;
}

测试结果如下:

A Constructor
AA Constructor
AA Function
AA Destructor
A Destructor
=======================
B Constructor
BB Constructor
BB Function
BB Destructor
B Destructor

测试父类指针指向子类实例代码:

/*-----------------------------------------------------------------------------
 *  测试子类转换为父类后,构造函数与析构函数顺序
 *-----------------------------------------------------------------------------*/
void test2()
{
    A *a = NULL;
    AA *aa = NULL;
    B *b = NULL;
    BB *bb = NULL;

    a = new AA();
    a->fun();
    delete a;
    cout<<"======================="<<endl;
    b = new BB();
    b->fun();
    delete b;
}

测试结果如下:

A Constructor
AA Constructor
A Function
A Destructor
=======================
B Constructor
BB Constructor
BB Function
BB Destructor
B Destructor

测试虚函数调用代码:

/*-----------------------------------------------------------------------------
 *  测试虚函数调用
 *-----------------------------------------------------------------------------*/
void test3()
{
    AA *aa = NULL;
    B *b = NULL;

    aa = new AA();
    aa->funA();
    delete aa;
    cout<<"======================="<<endl;
    b = new BB();
    b->funB();
    delete b;
}

测试结果如下:

A Constructor
AA Constructor
AA FunctionA
A Function
A FunctionA
AA Destructor
A Destructor
=======================
B Constructor
BB Constructor
BB Function
B Function
B FunctionB
BB Destructor
B Destructor








 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值