By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,849 Members | 2,164 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,849 IT Pros & Developers. It's quick & easy.

Compile time check for virtual destructor

P: n/a
Hi,
I decided to abandon the direct use of raw pointers in my programs and
intend to replace them with templates like:

dyn_array_of < typename T, typename Allocator >
pointer_to < typename T, typename Allocator >
polymorphic_ptr < typename T, typename Allocator >

I want pointer_to<T> to not allow for polymorphism whereas
polymorphic_ptr<T> should allow for this. Now, I would like
polymorphic_ptr<T> to perform a compile time check whether T has a virtual
destructor so that the compiler would choke on any atempt to use something
like polymorphic_ptr< std::string >.

Unfortunately, I do not see how I can do this. Here is a work around that
almost does it with gcc-3.4:

template < unsigned long M, unsigned long N >
class CHECK_is_equal {
private:

template < unsigned long A >
class XXX {
public:

void operator== ( const XXX & ) const {};

};

public:

CHECK_is_equal ( void ) {
XXX< M > a;
XXX< N > b;
a == b;
}

};

template < typename T >
class CHECK_is_polymorphic {
private:

class NonVirtual : public T {
public:

~NonVirtual ( void ) {}

};

class Virtual : public T {
public:

virtual ~Virtual ( void ) {}

};

public:

CHECK_is_polymorphic ( void ) {
CHECK_is_equal< sizeof( NonVirtual ), sizeof( Virtual ) > x;
}

};

struct BaseA {

virtual void f ( void ) {};

virtual ~BaseA ( void ) {}

};

struct BaseB {

virtual void f ( void ) {};

~BaseB ( void ) {}

};

struct BaseC {

void f ( void ) {};

virtual ~BaseC ( void ) {}

};

struct BaseD {

void f ( void ) {};

~BaseD ( void ) {}

};

int main ( void ) {
CHECK_is_polymorphic< BaseA > a;
CHECK_is_polymorphic< BaseB > b;
CHECK_is_polymorphic< BaseC > c;
CHECK_is_polymorphic< BaseD > d; // this line gives an error.
}

This does not check for a virtual destructor but for the existence of a
virtual function. Moreover, it depends on the implementation specific
feature that the pointer to the table of virtual function causes the type
size to increase.

Is there a standard way of checking for a virtual destructor?
Best

Kai-Uwe Bux
Jul 22 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
On Sun, 15 Aug 2004 10:23:10 -0400, Kai-Uwe Bux <jk********@gmx.net>
wrote:

[snip]
Is there a standard way of checking for a virtual destructor?


I don't know of one. I tried something, but soon gave up as I
discovered that it seems impossible to take the address of the
destructor (or declare a pointer to member for the destructor).

Seems like a bit of overkill, anyway ... if you need compile-time
checking, I would just look at the base class' declaration. If that
destructor is virtual, all derived destructors are also virtual.

It is perfectly legal to derive a class from a base class which has no
virtual destructor as long as the object is never deleted through a
pointer to the base class (e.g. using private inheritance).
--
Bob Hairgrove
No**********@Home.com
Jul 22 '05 #2

P: n/a

"Kai-Uwe Bux" <jk********@gmx.net> wrote in message news:cf**********@news01.cit.cornell.edu...

Is there a standard way of checking for a virtual destructor?


No, you're about hit it. There is no way to generally test for whether
a specific function (destructor or otherwise) is virtual. As you guessed,
your test for is_polymorphic is also dependent on implementation particulars.

You might be able to fix the general "is_polymorphic" test with some
concoction of dynamic_cast, as it's ill-formed to apply dynamic_cast
in some circumstances to non-polymorphic objects.

Jul 22 '05 #3

P: n/a
Ron Natalie wrote:

"Kai-Uwe Bux" <jk********@gmx.net> wrote in message
news:cf**********@news01.cit.cornell.edu...

Is there a standard way of checking for a virtual destructor?


No, you're about hit it. There is no way to generally test for whether
a specific function (destructor or otherwise) is virtual. As you
guessed, your test for is_polymorphic is also dependent on implementation
particulars.

You might be able to fix the general "is_polymorphic" test with some
concoction of dynamic_cast, as it's ill-formed to apply dynamic_cast
in some circumstances to non-polymorphic objects.

Thanks a lot, that is a great idea:

template < typename T >
class CHECK_is_polymorphic {
private:

struct XXX : public T {}

XXX* xxx ( T* ptr ) {
return( dynamic_cast< XXX* >( ptr ) );
}

public:

CHECK_is_polymorphic ( void ) {
T t;
xxx( &t );
}

};

This seems to do it. The error messages I get from g++ are frightening, and
maybe some improvements are in order; but the basic functionality seems to
be working. I can live with the shortcoming that the destructor still might
not be virtual -- the compiler issues warnings about that anyway.
Thanks again

Kai-Uwe Bux
Jul 22 '05 #4

P: n/a
On Sun, 15 Aug 2004 11:30:33 -0400, Kai-Uwe Bux <jk********@gmx.net>
wrote:
Ron Natalie wrote:

"Kai-Uwe Bux" <jk********@gmx.net> wrote in message
news:cf**********@news01.cit.cornell.edu...

Is there a standard way of checking for a virtual destructor?

No, you're about hit it. There is no way to generally test for whether
a specific function (destructor or otherwise) is virtual. As you
guessed, your test for is_polymorphic is also dependent on implementation
particulars.

You might be able to fix the general "is_polymorphic" test with some
concoction of dynamic_cast, as it's ill-formed to apply dynamic_cast
in some circumstances to non-polymorphic objects.

Thanks a lot, that is a great idea:

template < typename T >
class CHECK_is_polymorphic {
private:

struct XXX : public T {}

XXX* xxx ( T* ptr ) {
return( dynamic_cast< XXX* >( ptr ) );
}

public:

CHECK_is_polymorphic ( void ) {
T t;
xxx( &t );
}


You can simplify that a bit:

template < typename T >
class CHECK_is_polymorphic {
public:

static int const checker =
sizeof(dynamic_cast<void*>(static_cast<T*>(0)));
};

That way you don't need to instantiate the constructor to get the
error.
This seems to do it. The error messages I get from g++ are frightening, and
maybe some improvements are in order; but the basic functionality seems to
be working. I can live with the shortcoming that the destructor still might
not be virtual -- the compiler issues warnings about that anyway.


Boost has a portable version of is_polymorphic in its type traits
library. www.boost.org

Tom
Jul 22 '05 #5

P: n/a
tom_usenet wrote:
template < typename T >
class CHECK_is_polymorphic {
private:

struct XXX : public T {}

XXX* xxx ( T* ptr ) {
return( dynamic_cast< XXX* >( ptr ) );
}

public:

CHECK_is_polymorphic ( void ) {
T t;
xxx( &t );
}
You can simplify that a bit:

template < typename T >
class CHECK_is_polymorphic {
public:

static int const checker =
sizeof(dynamic_cast<void*>(static_cast<T*>(0)));
};

That way you don't need to instantiate the constructor to get the
error.


Thanks a lot,
I just put three lines into my polymorphic_ptr<T> template:

// CONCEPT CHECK: [T has to be polymorphic.]
static unsigned long const
CHECK_IS_POLYMORPHIC = sizeof( dynamic_cast<void*>( static_cast<T*>(0) ) );

And the best part is: the error message is way cleaner.

Boost has a portable version of is_polymorphic in its type traits
library. www.boost.org


I looked that up. It appears that their implementation is very much along
the lines of my first attempt (using sizeof to see whether a vtable gets
added when a virtual destructor is enforced). Since I am just looking for a
way to make the compiler choke on polymorphic_ptr< std::string >, this
seems too elaborate.
Thanks again

Kai-Uwe Bux
Jul 22 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.