此处未定义虚拟析构函数
No virtual destructor defined here
这在我的官方笔记中提供了,但我发现了一个错误。在我把它带到我的导师那里之前,我只是想在这里和我所有的血亲兄弟——你们——确认一下。
#include <iostream.h>
class Base {
public:
virtual void display() { cout << "Base class" << endl; }
};
class Derived: public Base {
// Nothing here
};
void main()
{
Base * ptr;
// Calls Base::display ( )
ptr = new Base ;
ptr ->display();
delete ptr ;
// Calls Base::display ( ) again
ptr = new Derived ;
ptr ->display();
delete ptr ;
}
输出为:
Base class
Base class
我认为问题出在主函数的最后一行。我的意思是,由于析构函数不是虚拟的,我认为您无法使用基类类型的指针删除派生类类型的动态分配实例。你觉得怎么样?
我的意思是,由于析构函数不是虚拟的,我认为您无法使用基类类型的指针删除派生类类型的动态分配实例。你觉得怎么样?
您可以在此处和此处看到这是未定义的行为。
如果基类没有虚拟析构函数,则此类代码的行为是未定义的。
从C++标准:
5.3.5 删除
3 在第一种替代方法(删除对象(中,如果操作数的静态类型与其动态类型不同,则静态类型应为操作数的动态类型的基类,静态类型应具有虚拟析构函数或行为未定义。
当一个函数被定义为虚拟时,编译器将使用动态绑定的指向基的指针来调用该函数,即对实际函数的调用将通过类 vTable 来查找函数的相关实现。如果一个函数没有被定义为虚拟的,那么编译器生成的代码将使用静态绑定,即编译器将简单地调用它知道的函数。换句话说,如果在指向派生类的基类指针上调用非虚函数,则编译器将生成用于调用基类实现的代码。
现在,析构函数行为只是上述一般行为的一个私人案例。由于在没有析构函数实现的情况下,编译器将为您生成默认的非虚拟析构函数,使用基类指针销毁对象将仅调用基类析构函数。通过显式定义基类和派生类的非虚拟析构函数,并使用调试器查看基类版本是否为被调用的版本,可以轻松重现此行为。
相关文章:
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- 是否可以使用函数指针调用虚拟析构函数?
- 在没有动态内存的世界中,我是否需要虚拟析构函数?
- "虚拟""覆盖"析构函数
- 程序永远不会进入虚拟析构函数
- C++ std::vector 中的虚拟析构函数继承
- 哪种方法更适合处理虚拟析构函数?
- 拥有"受保护的非虚拟析构函数"与"受保护虚拟析构构函数"有什么好处
- 带有未解析外部元素的C++虚拟析构函数
- 即使基类和派生类只使用基元数据类型,我是否需要定义虚拟析构函数
- 从内部类的析构函数调用虚拟函数
- C++切片和虚拟析构函数
- C++虚拟继承、虚拟析构函数和 dynamic_cast<void*>
- 添加虚拟析构函数会使代码大小膨胀
- 应该是虚拟析构函数吗?但是怎么做呢?
- 虚拟析构函数将对象移出 rodata 部分
- 为什么虚拟类的析构函数不会自动添加到 vtable 中?
- 如何将 std::unique_ptr<Parent> 与具有受保护虚拟析构函数的只读父类一起使用
- DIRECTX9 中自定义顶点的虚拟析构函数
- 声明析构函数虚拟就足够了吗?