随笔 - 51, 文章 - 1, 评论 - 41, 引用 - 0
数据加载中……

CPPEXP —— 构造析构函数调用顺序

## 说明

构造函数的调用顺序是先父类再子类。析构函数的顺序相反——先子类再父类。有继承关系的类的析构函数需要声明为virtual,但并非必须。声明virtual表明函数不能再编译期间确定,只有在运行时才能确定。这样的场景是删除基类指针,但其指向是派生类。此时编译器看到的只有基类信息,如果没有声明virtual,就没有虚函数表或者虚函数表没有析构函数项,只能调用基类的析构函数。如果不声明virtual,将子类指针赋值给父类指针是有风险的操作。



## 实验代码


```C

/**

 * @file constructor_destructor_sequence.cpp

 * @brief 测试构造析构函数的调用次序

 * @copyright public domain

 */


#include <iostream>


class Base {

public:

    Base() { std::cout << "Base()" << std::endl; }

    ~Base() { std::cout << "~Base()" << std::endl; }

};


class VBase {

public:

    VBase() { std::cout << "VBase()" << std::endl; }

    virtual ~VBase() { std::cout << "~VBase()" << std::endl; }

};


class Derived : public Base {

public:

    Derived() { std::cout << "Derived()" << std::endl; }

    ~Derived() { std::cout << "~Derived()" << std::endl; }

};


class VDerived: public VBase {

public:

    Derived() { std::cout << "VDerived()" << std::endl; }

    ~VDerived() { std::cout << "~VDerived()" << std::endl; }

};


void test_0() {

    std::cout <<"子类不声明virtual,按基类指针删除派生类" << std::endl;

    VBase* p = new VDerived;

    delete p;

}


void test_1() {

    std::cout <<"不声明virtual,按派生类指针删除派生类" << std::endl;

    Derived* p = new Derived;

    delete p;

}


void test_2() {

    std::cout <<"不声明virtual,按基类指针删除派生类" << std::endl;

    Base* p = new Derived;

    delete p;

}


void test_3() {

    std::cout <<"不声明virtual,按void*删除派生类" << std::endl;

    void* p = new Derived;

    delete p;

}


int main() {

    test_0();

    test_1();

    test_2();

    test_3();


    return 0;

}

```


## 运行及结果


    > g++ constructor_destructor_sequence.cpp

    constructor_destructor_sequence.cpp: In function 'void test_3()':

    constructor_destructor_sequence.cpp:54:9: warning: deleting 'void*' is undefined [enabled by default]


    > a.exe

    子类不声明virtual,按基类指针删除派生类

    VBase()

    VDerived()

    ~VDerived()

    ~VBase()

    不声明virtual,按派生类指针删除派生类

    Base()

    Derived()

    ~Derived()

    ~Base()

    不声明virtual,按基类指针删除派生类

    Base()

    Derived()

    ~Base()

    不声明virtual,按void*删除派生类

    Base()

    Derived()







posted on 2016-04-23 18:26 lemene 阅读(299) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理