基类函数被调用两次

Base class function gets called twice

本文关键字:两次 类函数 调用 基类      更新时间:2023-10-16

我有一个基类和一个派生类。我想让用户决定何时free()两个类分配的内存,这些函数也将由类的析构函数调用。

然而,这种方法强制调用基类free()函数两次,第一次来自派生类free()函数,第二次来自基类析构函数。

class Base
{
public:
    Base() {
        _baseVal = new int(4);
        cout << "base constructorn";
    }
    virtual void free()
    {
        if(_baseVal) {
            delete _baseVal;
            _baseVal = 0;
        }
        cout << "base free()n";
    }
    virtual ~Base() {
        free();
    }

private:
    int *_baseVal;
};
class Derived : public Base
{
public:
    Derived() {
        _derivedVal = new int(10);
        cout << "derived constructorn";
    }
    void free()
    {
        Base::free();
        if(_derivedVal) {
            delete _derivedVal;
            _derivedVal = 0;
        }
        cout << "derived free()n";
    }
    ~Derived() {
        free();
    }

private:
    int *_derivedVal;
};

int main()
{
    Base *der = new Derived;
    delete der;
    system("pause");
    return 0;
}

输出:

base constructor
derived constructor
base free()
derived free()
base free()

这种方法有没有办法不强制调用基free()两次?

析构函数不会调用两次,但Base::free()会调用两次。区别很重要,因为后者是您自己的类方法。析构函数由编译器调用,并且只调用一次。

Derived对象超出作用域时,首先调用它自己的析构函数。在Derived::~Derived中,您可以调用Derived::free()。你在那里做的第一件事,就是调用Base::free()。然后处理派生类逻辑的其余部分。当Derived部分被清理后,执行Base部分的析构函数,该析构函数本身调用Base::free()

原则上,这里没有问题,因为您确保Base::free()在已经运行的情况下不会执行任何操作(通过将_baseVal设置为空指针)。但是,您可以通过从Derived::free()中删除对Base::free()的调用来避免这种情况,因为Base析构函数将保证Base::free()至少运行一次。