可更新接口中的虚拟析构函数可以吗?
are virtual destructors in novtable interfaces okay?
我有一个Visual Studio 2008 C++03项目,其中我有一个声明为_declspec( novtable )
的接口类。例如:
class _declspec( novtable ) IFoo
{
public:
virtual void FooDo() const = 0;
};
class Foo : public IFoo
{
public:
~Foo() { printf( "~Foo()rn" ); };
void FooDo() const { printf( "FooDo()rn" ); };
};
int main( int argc, char* argv[] )
{
IFoo* foo = new Foo();
foo->FooDo();
delete foo;
return 0;
}
由于IFoo
没有虚拟析构函数,因此永远不会调用具体的Foo
析构函数。
输出:
FooDo()
期望输出:
FooDo()
~Foo()
但是,在 MSDN 中,有一个可怕的警告,不要在声明为 novtable
的接口类中调用函数。"如果您尝试实例化标记为 novtable 的类,然后访问类成员,您将收到访问冲突 (AV)。因此,添加virtual ~IFoo() { };
成员听起来可能是一件坏事。(尽管在我的测试中,它似乎工作正常。
如何从中正确获得所需的行为?
在
接口类中包含虚拟析构函数应该没问题。您已经包含另一个虚拟方法并调用了它,因此析构函数应该没有什么不同。
novtable
的效果是IFoo
的 vtable 不会被初始化。不过没关系,因为您从不直接实例化IFoo
。相反,您可以实例化该类的后代。后代有一个 vtable,并且该 vtable 使用指向Foo
方法的指针正确初始化(和IFoo
,如果IFoo
有任何Foo
不覆盖的非纯虚拟方法)。从 Foo
内部调用~IFoo
是非虚拟调度,因此仍然不需要 IFoo
的 vtable。
相关文章:
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- 是否可以使用函数指针调用虚拟析构函数?
- 在没有动态内存的世界中,我是否需要虚拟析构函数?
- "虚拟""覆盖"析构函数
- 程序永远不会进入虚拟析构函数
- C++ std::vector 中的虚拟析构函数继承
- 哪种方法更适合处理虚拟析构函数?
- 拥有"受保护的非虚拟析构函数"与"受保护虚拟析构构函数"有什么好处
- 带有未解析外部元素的C++虚拟析构函数
- 即使基类和派生类只使用基元数据类型,我是否需要定义虚拟析构函数
- 从内部类的析构函数调用虚拟函数
- C++切片和虚拟析构函数
- C++虚拟继承、虚拟析构函数和 dynamic_cast<void*>
- 添加虚拟析构函数会使代码大小膨胀
- 应该是虚拟析构函数吗?但是怎么做呢?
- 虚拟析构函数将对象移出 rodata 部分
- 为什么虚拟类的析构函数不会自动添加到 vtable 中?
- 如何将 std::unique_ptr<Parent> 与具有受保护虚拟析构函数的只读父类一起使用
- DIRECTX9 中自定义顶点的虚拟析构函数
- 声明析构函数虚拟就足够了吗?