我有一个基类和一个派生类。我想让用户决定何时free()
两个类分配的内存,这些函数也将被类调用。析构函数。
但是,这种方法强制基类free()
函数被调用两次,第一次来自派生类free()
函数,第二次来自基础析构函数。
class Base
{
public:
Base() {
_baseVal = new int(4);
cout << "base constructor\n";
}
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 constructor\n";
}
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()
被调用两次?
答案 0 :(得分:1)
析构函数不会被调用两次,但Base::free()
被调用两次。差异很重要,因为后者是你自己的类方法。析构函数由编译器调用,只调用一次。
当Derived
对象超出范围时,首先调用它自己的析构函数。在Derived::~Derived
中,您拨打Derived::free()
。你在那里做的第一件事就是打电话Base::free()
。然后处理派生类逻辑的其余部分。清除Derived
部分后,将执行Base
部分的析构函数,该析构函数本身会调用Base::free()
。
原则上你在这里没有问题,因为你确保Base::free()
如果已经运行(通过将_baseVal
设置为空指针),它就不会做任何事情。您可以通过从Base::free()
移除对Derived::free()
的调用来避免此问题,因为Base
析构函数将保证Base::free()
至少运行一次。