Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

are virtual destructors in novtable interfaces okay?

Tags:

c++

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?

like image 650
PaulH Avatar asked Oct 20 '25 10:10

PaulH


1 Answers

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 novtable is that the vtable of IFoo doesn't get initialized. That's OK, though, since you never directly instantiate IFoo. Instead, you instantiate a descendant of that class. The descendant has a vtable, and that vtable gets initialized properly with pointers to methods of Foo (and IFoo, if IFoo has any non-pure virtual methods that Foo doesn't override). The call to ~IFoo from within Foo is a non-virtual dispatch, so the vtable of IFoo still isn't required.

like image 75
Rob Kennedy Avatar answered Oct 23 '25 00:10

Rob Kennedy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!