如果基类析构函数是虚拟的,是否需要派生类析构函数定义
Is a derived class destructor definition required if base class destructor is virtual?
我正在尝试以下示例:
class base // base class
{
public:
std::list<base*> values;
base(){}
void initialize(base *b) {
values.push_front(b);
}
virtual ~base()
{
values.clear();
cout<<"base called"<<endl;
}
};
class derived : public base // derived class
{
public:
~derived(){
cout<<"derived called"<<endl;
}
};
int main()
{
derived *d = new derived;
base *b = new base;
b->initialize(static_cast<base *>(d)); /* filling list */
delete b;
return 0;
}
Q.1)为什么没有调用派生类的析构函数,就像我在values.clear()
执行的基类析构函数一样?
Q.2) 如果基类析构函数是虚拟的,是否需要派生类析构函数定义?
Q1。因为您没有删除类型为 derived
的对象。您只执行 delete b;
,这会删除base
。您还应该致电delete d;
。
此外,还应指定负责内存管理的对象。您的设计容易出错。您最好使用智能指针来防止歧义。此外,为了按预期运行,析构函数应为:
virtual ~base()
{
for ( int i = 0 ; i < values.size() ; i++ )
delete values[i];
values.clear();
cout<<"base called"<<endl;
}
当然,使用这种方法,在main
中调用delete d;
将是未定义的行为。
问题 2.不,定义不是必需的。
为什么没有调用派生类的析构函数,就像我在基类析构函数中执行的那样
values.clear();
values.clear()
从此列表中删除所有指针。它不会删除指向的对象;这将是非常危险的,因为该列表无法知道它是否对它们的生命周期负责,或者它们是否只是用来引用在其他地方管理的对象。
如果您希望列表拥有对象,则必须在删除对象时自行删除它们,或者存储智能指针,例如 std::unique_ptr<base>
。如果您的编译器不支持新的智能指针,那么您可能会发现 Boost 的指针容器库很有用。
是否需要派生类析构函数定义。如果基类析构函数是虚拟的。
仅当派生类中存在需要清理的内容时,才需要它。如果它无事可做,则无需定义一个空的。
你实际上并没有delete d
,所以当然不会调用析构函数。要么使d静态分配(derived d
而不是derived *d = new derived
),要么调用delete d
。
如果未在派生类中声明析构函数,则将创建默认析构函数。仍会调用基类析构函数,请参阅常见问题解答 (11.12)。另请注意,由于基类析构函数是虚拟的,因此派生类析构函数会自动成为虚拟的(无论是否定义),请参阅常见问题解答 (20.7)。
为什么你认为应该调用派生类的析构函数?您只删除基,它是基类的实例。
不,析构函数的定义不是必需的 - 您可以省略它。
- 使用基类指针创建对象时,缺少派生类析构函数
- 添加自定义析构函数时,Move 构造函数在派生类中消失
- 从 c++ 中派生类的析构函数调用虚函数
- 如何从 Gtk::窗口调用派生对象的析构函数
- 在派生类中将公共父析构函数设为私有
- 即使基类和派生类只使用基元数据类型,我是否需要定义虚拟析构函数
- C++11:我可以显式调用基类析构函数来销毁派生类吗
- 在从仅移动类型派生的类中定义析构函数在使用 std::vector emplace_back或push_back创建时会
- 受保护的析构函数禁用在堆栈上创建派生类的对象?
- 防止派生析构函数中的 vtable 数据争用
- 如何在另一个类的向量中调用派生类的析构函数
- 了解派生类中C++析构函数的行为
- 私有派生析构函数
- 在派生类中重写哪个基类的虚拟析构函数
- 基类没有析构函数,但派生类有析构函数。我是否需要寻找与堆无关的任何陷阱?
- 显式声明派生类中所需的析构函数
- 调用派生类的析构函数
- 在这种情况下,我的派生类是否还需要一个虚拟析构函数
- g++对基类析构函数和派生类指针的未定义引用
- 通过 BaseClass List 调用派生类对象的析构函数