在C ++中从虚拟析构函数调用虚方法

时间:2017-03-21 14:15:22

标签: c++ memory-management memory-leaks destructor

我想破坏类B的对象。

class A {
public:
    A() {
        std::cout << "construct A" << av::endl;
        a = new int;
    }
    virtual ~A() {
        std::cout << "destruct A" << av::endl;
        this->clear();
    }
    virtual void clear() {
        std::cout << "clear A" << av::endl;
        delete a;
    }
protected:
    int *a;
};

class B : public A {
public:
    B() {
        std::cout << "construct B" << av::endl;
        b = new int;
    }
    ~B() {
        std::cout << "destruct B" << av::endl;
    }
    void clear() override {
        std::cout << "clear B" << av::endl;
        delete b;
        delete this->a;
    }
private:
    int *b;
};

我希望用clear()方法完成它。但是当我执行以下代码时:

A *a = new B();
delete a;

我明白了:

  

构造A构造B破坏B破坏A clear A

永远不会打印clear B。 我做错了什么?

1 个答案:

答案 0 :(得分:5)

非正式地,在~A();中,B部分已被破坏,调用B的任何函数都没有任何意义。

有效的C ++项目9:永远不要在构造或销毁期间调用虚函数。

  

派生类析构函数运行后,该对象的派生类   数据成员假定未定义的值,因此C ++将它们视为没有   更长的存在。在进入基类析构函数时,该对象   成为基类对象,以及C ++的所有部分 - 虚函数,   dynamic_cast s等,以这种方式来保护它。