What to do with destructors in the interface

When I write interface classes in C ++, I choose one of the following two options

class Interface { public: virtual R1 f1(p11, p12 , ...) = 0; ... virtual Rn fn(pn1, pn2 , ...) = 0; virtual ~Interface() {} } 

or

 class Interface { public: virtual R1 f1(p11, p12 , ...) = 0; ... virtual Rn fn(pn1, pn2 , ...) = 0; virtual ~Interface() = 0; } Interface::~Interface() {} 

The first version is shorter for recording
The second is attractive in that all the interface functions are pure virtual

Is there any reason why I should prefer one or the other method (or perhaps the third)?
Thanks

+7
source share
4 answers

As I understand it, the purpose of a virtual virtual function is virtual, to force derived classes to either provide an implementation for it, or select a default implementation by explicitly writing Base::f() in Derived::f() .

So, if so, what is the purpose of creating a pure virtual virtual destructor? Does it force derived classes to provide an implementation for Base::~Base() ? Can derived classes implement Base::~Base() ? Not.

Thus, the first version with a virtual destructor seems sufficient for almost all purposes. In the end, the most common goal of a virtual destructor is that clients can correctly delete objects of derived classes through pointers of type Base* .

However, if you make all functions in Base only virtual, not pure virtual and provide them with an implementation (in fact you should provide), and at the same time you want to make Base abstract type, then having a pure virtual destructor in Base is the only solution :

 class Base { public: virtual void f() {}; //not pure virtual virtual ~Base() = 0; //pure - makes Base abstract type! }; Base::~Base() {} //yes, you have to do this as well. Base *pBase = new Base(); // error - cannot create instance! 

Hope this helps.

+5
source

For me, dtor is not part of the interface. Fi () will have analogues in other languages, not dtor. Similarly, you can write pre and post conditions for fi (), but not dtor. This makes it just a C ++ wart, and the first technique is the most convenient way to deal with it.

+2
source

In the first case, the derived class can choose whether to implement a destructor. In the second case, the pure virtual destructor must be overridden, so the derived class is forced to implement the destructor.

If you have no reason why you want to do this, I would go in the first case.

+1
source

Ok, I found the link and therefore thought that I would call it the answer:

Are the built-in virtual functions really meaningless?

I saw compilers that do not emit any v-column if no inline function exists at all (and is defined in one implementation file instead of a header then). They will throw errors like vtable-for-class-A or something like that is missing and you would be embarrassed as hell like me.

Indeed, this does not comply with the Standard, but it is so that at least one virtual function is not in the header (if only a virtual destructor), so the compiler can emit a vtable for the class at that place. I know this happens with some versions of gcc. ( Johannes Schaub )

It is slightly different from your second case (assuming that it actually outputs the function from the header file as a whole so as not to fall prey to the gcc problem), but I thought I mentioned this. Gcc quirks can sometimes bite.

+1
source

All Articles