[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

Pure virtual destructor in template class

Tonni Tielens

11/18/2008 4:34:00 PM

I'm trying to create a pure virtual class describing an interface.
Normally, when I do this I make the destructor pure virtual so that,
even if there are no members in the class, it cannot be instantiated.

The difference now is that I'm making a generic interface with
template arguments. Template classes should be defined in the header
file, but it is not allowed for a destructor's definition to be in the
class definition if the destructor is pure virtual. Atleast not with
GCC -pedantic and I understand this is correct behavior. I'm unsure on
how to solve this. I know I don't really have to put a pure virtual
destructor in the class, but I think it's good practice so if it's
possible I would like to stick to this.

My code looks like the following:


template <typename TypeA, typename TypeB>
struct MyInterface
{
virtual ~MyInterface() = 0;

virtual void Foo(TypeA a, TypeB b) = 0;
};


I already found that I can resolve the compilation errors, by adding


template <typename TypeA, typename TypeB>
MyInterface<TypeA, TypeB>::~MyInterface() {}


in the same file after the class definition, but I'm not sure if this
is the common way to do this. Is there a correct way to do this or
should I leave the pure virtual destructor out?
8 Answers

Victor Bazarov

11/18/2008 4:52:00 PM

0

Tonni Tielens wrote:
> I'm trying to create a pure virtual class describing an interface.
> Normally, when I do this I make the destructor pure virtual so that,
> even if there are no members in the class, it cannot be instantiated.

Why would you have an interface with no other members? Wouldn't it be
pretty much useless as an interface?

> The difference now is that I'm making a generic interface with
> template arguments. Template classes should be defined in the header
> file, but it is not allowed for a destructor's definition to be in the
> class definition if the destructor is pure virtual. Atleast not with
> GCC -pedantic and I understand this is correct behavior. I'm unsure on
> how to solve this. I know I don't really have to put a pure virtual
> destructor in the class, but I think it's good practice so if it's
> possible I would like to stick to this.
>
> My code looks like the following:
>
>
> template <typename TypeA, typename TypeB>
> struct MyInterface
> {
> virtual ~MyInterface() = 0;
>
> virtual void Foo(TypeA a, TypeB b) = 0;
> };
>
>
> I already found that I can resolve the compilation errors, by adding
>
>
> template <typename TypeA, typename TypeB>
> MyInterface<TypeA, TypeB>::~MyInterface() {}
>
>
> in the same file after the class definition, but I'm not sure if this
> is the common way to do this. Is there a correct way to do this or
> should I leave the pure virtual destructor out?

If your destructor doesn't do anything, you can give it an empty body
right in the class definition. Since you have other virtual functions
in your interface, they will be pure and the destructor doesn't have to
be. But if you just *want* your destructor pure, your solution is just
what the doctor ordered. Idiomatic.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Pete Becker

11/18/2008 4:53:00 PM

0

On 2008-11-18 11:33:49 -0500, Tonni Tielens <tonnitielens@gmail.com> said:

> I'm trying to create a pure virtual class describing an interface.

There's no such thing as a pure virtual class. The term you're looking
for is abstract class.

> Normally, when I do this I make the destructor pure virtual so that,
> even if there are no members in the class, it cannot be instantiated.
>
> The difference now is that I'm making a generic interface with
> template arguments. Template classes should be defined in the header
> file, but it is not allowed for a destructor's definition to be in the
> class definition if the destructor is pure virtual. Atleast not with
> GCC -pedantic and I understand this is correct behavior. I'm unsure on
> how to solve this. I know I don't really have to put a pure virtual
> destructor in the class, but I think it's good practice so if it's
> possible I would like to stick to this.
>
> My code looks like the following:
>
>
> template <typename TypeA, typename TypeB>
> struct MyInterface
> {
> virtual ~MyInterface() = 0;
>
> virtual void Foo(TypeA a, TypeB b) = 0;
> };
>
>
> I already found that I can resolve the compilation errors, by adding
>
>
> template <typename TypeA, typename TypeB>
> MyInterface<TypeA, TypeB>::~MyInterface() {}
>
>
> in the same file after the class definition, but I'm not sure if this
> is the common way to do this.

It is.

> Is there a correct way to do this or
> should I leave the pure virtual destructor out?

You can't leave the destructor out. Try it.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Pete Becker

11/18/2008 5:07:00 PM

0

On 2008-11-18 11:52:08 -0500, Victor Bazarov <v.Abazarov@comAcast.net> said:

> Tonni Tielens wrote:
>> I'm trying to create a pure virtual class describing an interface.
>> Normally, when I do this I make the destructor pure virtual so that,
>> even if there are no members in the class, it cannot be instantiated.
>
> Why would you have an interface with no other members? Wouldn't it be
> pretty much useless as an interface?

It's a Java thing. For example, if a class that implements
java.util.List (which is, roughly, a linked list) also implements
java.util.RandomAccess, it announces that it supports constant-time
random access to elements, so a loop like this:

for (int i = 0, n = list.size(); i <n; i++)
list.get(i);

will supposedly be faster than a loop like this:

for (Iterator i = list.iterator(); i.hasNext(); )
i.next();

You'd use a runtime type check to decide which way to go.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Tonni Tielens

11/18/2008 6:26:00 PM

0

On Nov 18, 5:52 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> Why would you have an interface with no other members?  Wouldn't it be
> pretty much useless as an interface?

It's just a way (and I believe a common way) of telling a class is
abstract without having the need to have any abstract members.
Consider Java or C# where you can define an interface without having
any methods. Completely useless, but perfectly legal. Normally, since
it is almost no effort, I make the destructor pure virtual, but since
it is more effort here and I'm going to add pure virtual methods
anyway, I will leave it out and let the compiler generate a default
one.

Thanks for the replies.

Victor Bazarov

11/18/2008 6:43:00 PM

0

Tonni Tielens wrote:
> On Nov 18, 5:52 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
>> Why would you have an interface with no other members? Wouldn't it be
>> pretty much useless as an interface?
>
> It's just a way (and I believe a common way) of telling a class is
> abstract without having the need to have any abstract members.
> Consider Java or C# where you can define an interface without having
> any methods. Completely useless, but perfectly legal. Normally, since
> it is almost no effort, I make the destructor pure virtual, but since
> it is more effort here and I'm going to add pure virtual methods
> anyway, I will leave it out and let the compiler generate a default
> one.

No, don't let the compiler do it because in that case it wouldn't be
virtual. You *do* need the destructor to be virtual, trust me.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Tonni Tielens

11/18/2008 6:57:00 PM

0

On Nov 18, 7:42 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> No, don't let the compiler do it because in that case it wouldn't be
> virtual.  You *do* need the destructor to be virtual, trust me.


Ah, you're completely right. I wasn't thinking while posting that. :)

James Kanze

11/18/2008 10:49:00 PM

0

On Nov 18, 6:06 pm, Pete Becker <p...@versatilecoding.com> wrote:
> On 2008-11-18 11:52:08 -0500, Victor Bazarov <v.Abaza...@comAcast.net> said:

> > Tonni Tielens wrote:
> >> I'm trying to create a pure virtual class describing an
> >> interface. Normally, when I do this I make the destructor
> >> pure virtual so that, even if there are no members in the
> >> class, it cannot be instantiated.

> > Why would you have an interface with no other members?
> >  Wouldn't it be pretty much useless as an interface?

> It's a Java thing.

I don't think it's only Java. It's known as a tagging
interface, and it potentially has a role in any staticly typed
language which supports polymorphism. I think I've actually
used it once in C++; C++ usually has other ways of solving the
problem, however, which are generally preferred (because they
can be made to work with non class types as well). Even in the
standard, the iterator_tag hierarchy could be considered an
example of this.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Pete Becker

11/18/2008 10:55:00 PM

0

On 2008-11-18 17:48:34 -0500, James Kanze <james.kanze@gmail.com> said:

> On Nov 18, 6:06 pm, Pete Becker <p...@versatilecoding.com> wrote:
>> On 2008-11-18 11:52:08 -0500, Victor Bazarov <v.Abaza...@comAcast.net> sa
> id:
>
>>> Tonni Tielens wrote:
>>>> I'm trying to create a pure virtual class describing an
>>>> interface. Normally, when I do this I make the destructor
>>>> pure virtual so that, even if there are no members in the
>>>> class, it cannot be instantiated.
>
>>> Why would you have an interface with no other members?
>>>  Wouldn't it be pretty much useless as an interface?
>
>> It's a Java thing.
>
> I don't think it's only Java. It's known as a tagging
> interface, and it potentially has a role in any staticly typed
> language which supports polymorphism. I think I've actually
> used it once in C++; C++ usually has other ways of solving the
> problem, however, which are generally preferred (because they
> can be made to work with non class types as well). Even in the
> standard, the iterator_tag hierarchy could be considered an
> example of this.

Well, maybe, but for that you don't need a virtual destructor. In the
part of my message that you snipped I pointed out how this is used in
Java. The analogous usage in C++ does require a virtual destructor in
order to be able to test for that (mixin) base with dynamic_cast.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)