I have a Visual Studio 2008 C++03 project where I have an interface class that is declared _declspec( novtable ). For example:
class _declspec( novtable ) IFoo
{
public:
virtual void FooDo() const = 0;
};
class Foo : public IFoo
{
public:
~Foo() { printf( "~Foo()\r\n" ); };
void FooDo() const { printf( "FooDo()\r\n" ); };
};
int main( int argc, char* argv[] )
{
IFoo* foo = new Foo();
foo->FooDo();
delete foo;
return 0;
}
Because IFoo does not have a virtual destructor, the concrete Foo destructor is never called.
Output:
FooDo()
Desired Output:
FooDo()
~Foo()
But, in MSDN, there is a dire warning against calling functions in interface classes declared novtable. “If you attempt to instantiate a class marked with novtable and then access a class member, you will receive an access violation (AV).” So adding a virtual ~IFoo() { }; member sounds like it could be a Bad Thing. (although in my testing, it seems to work fine.)
How does one properly get the desired behavior from this?
It should be fine to include a virtual destructor in your interface class. You’ve already included another virtual method and called it, so the destructor should be no different.
The effect of
novtableis that the vtable ofIFoodoesn’t get initialized. That’s OK, though, since you never directly instantiateIFoo. Instead, you instantiate a descendant of that class. The descendant has a vtable, and that vtable gets initialized properly with pointers to methods ofFoo(andIFoo, ifIFoohas any non-pure virtual methods thatFoodoesn’t override). The call to~IFoofrom withinFoois a non-virtual dispatch, so the vtable ofIFoostill isn’t required.