Interfaces and non-virtual destructors

M

Marcel Müller

If i have an interface like

template <class K>
struct IComparableTo
{ virtual int compareTo(const K& key) const = 0;
};

some compilers (e.g. gcc) warn me about that the class has virtual
functions but a non-virtual destructor. While this can be helpful in
some cases, it can be annoying too.
If the interface is a template like in the example I get hundreds of
warnings for each type instantiation in each compilation unit.

From the applications point of view it might be not reasonable to
delete the entire object through a particular interface. In such cases I
usually write

template <class K>
struct IComparableTo
{ virtual int compareTo(const K& key) const = 0;
protected:
~ICompareableTo() {}
};

to avoid accidental deletion. But the warnings still hide other, more
important messages.

Is there another way to declare interfaces?
Or are there other good reasons to have virtual destructors on interface
classes?


Marcel
 
E

Erik Wikström

If i have an interface like

template <class K>
struct IComparableTo
{ virtual int compareTo(const K& key) const = 0;
};

some compilers (e.g. gcc) warn me about that the class has virtual
functions but a non-virtual destructor. While this can be helpful in
some cases, it can be annoying too.
If the interface is a template like in the example I get hundreds of
warnings for each type instantiation in each compilation unit.

From the applications point of view it might be not reasonable to
delete the entire object through a particular interface. In such cases I
usually write

template <class K>
struct IComparableTo
{ virtual int compareTo(const K& key) const = 0;
protected:
~ICompareableTo() {}
};

to avoid accidental deletion. But the warnings still hide other, more
important messages.

Is there another way to declare interfaces?
Or are there other good reasons to have virtual destructors on interface
classes?

Yes, the reason is the same as why you should have a virtual destructor
in a base-class. If someone have a pointer of type IComarableTo which
points to a class implementing the interface and then use delete on the
pointer you want IComparableTo to have a virtual destructor.

See also:
http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.7
 
K

Kai-Uwe Bux

Erik said:
Yes, the reason is the same as why you should have a virtual destructor
in a base-class. If someone have a pointer of type IComarableTo which
points to a class implementing the interface and then use delete on the
pointer you want IComparableTo to have a virtual destructor.
[snip]

I think you may have missed the point of the OP. Consider the IComparableTo
example:

template < typename K >
struct IComparableTo {

virtual int compareTo(const K& key) const = 0;

protected:

~IComparableTo() {}

};

struct XXX : public IComparableTo<int> {

int compareTo( int const & key ) const {
return ( 0 );
}

virtual ~XXX ( void ) {}

};

int main ( void ) {
IComparableTo<int> * iptr = new XXX;
XXX * xptr = new XXX;
delete xptr; // fine
delete iptr; // illegal
}

The OP has designed the interface class so that deleting derived objects
_through_ the interface is forbidden. Thus, the reason you cite for virtual
destructors does not apply.


Best

Kai-Uwe Bux
 
G

Gennaro Prota

Marcel said:
If i have an interface like

template <class K>
struct IComparableTo
{ virtual int compareTo(const K& key) const = 0;
};

some compilers (e.g. gcc) warn me about that the class has virtual
functions but a non-virtual destructor. While this can be helpful in
some cases, it can be annoying too.
If the interface is a template like in the example I get hundreds of
warnings for each type instantiation in each compilation unit.

From the applications point of view it might be not reasonable to
delete the entire object through a particular interface. In such cases I
usually write

template <class K>
struct IComparableTo
{ virtual int compareTo(const K& key) const = 0;
protected:
~ICompareableTo() {}
};

to avoid accidental deletion. But the warnings still hide other, more
important messages.

Is there another way to declare interfaces?

Yes, with the class keyword :) No, just kidding, of course... there's
no problem in your code. What version of gcc are you using? I have up
to 4.1.1 (built yesterday -hurrah!), and it still emits the warning.
*Perhaps* they fixed that in 4.2 or 4.3 (when the destructor is
protected and the class declares no friends). It's a long-standing
annoyance.

(Off-hand, I think it would require a trivial change in cp/class.c; I
have no idea why they haven't fixed it yet)
 
G

Gennaro Prota

Gennaro said:
*Perhaps* they fixed that in 4.2 or 4.3 (when the destructor is
protected and the class declares no friends). It's a long-standing
annoyance.

I was curious and had a look at the SVN repository. It's fixed. They
seem to have first forgotten the protected case, then found the right
form:

<http://gcc.gnu.org/viewcvs/trunk/gcc/cp/class.c?r1=127154&r2=127649>

Revision 127649 means that this (the right form for the protected
case) went into gcc 4.2.2.
 
M

Marcel Müller

Gennaro said:
I was curious and had a look at the SVN repository. It's fixed. They
seem to have first forgotten the protected case, then found the right form:

<http://gcc.gnu.org/viewcvs/trunk/gcc/cp/class.c?r1=127154&r2=127649>

Revision 127649 means that this (the right form for the protected case)
went into gcc 4.2.2.

Oh, nice to hear. Unfortunately I am fixed to Gcc 3.3.5, because Gcc 4
is not yet ported for OS/2. So I will seek for a command line switch
that disables exactly this warning without affecting the others, as Pete
recommended.


Marcel
 
G

Gennaro Prota

Pete said:
That's what happens when compiler writers assume that they know more
about your application than you do. Surely, though, there's a
command-line switch to turn off this warning.

Well, compiler warnings are meant to catch programmer's oversights.
There's always a trade-off between their helpfulness, risk of false
positives and corresponding compiler complexity. With gcc 4.2.2 (see
my other post) that's IMHO quite a good trade-off.

For the records, you can disable the warning with -Wno-non-virtual-dtor.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,062
Latest member
OrderKetozenseACV

Latest Threads

Top