Home » Coding » c++ » cast classes to common ancestor
cast classes to common ancestor [message #17371] Sat, 06 October 2007 22:04 Go to next message
deadguysfrom  is currently offline deadguysfrom
Messages: 1
Registered: October 2007
Junior Member
Ive got two classes in the same class hierarchy, and I want to find
their common ancestor. Any idea how to do this?

class A {};
class B : public A {};
class C : public B {};
class D : public B {};

I have pointers to C and D, I want pointers to B.

thanks
Re: cast classes to common ancestor [message #17372 is a reply to message #17371 ] Sat, 06 October 2007 22:31 Go to previous messageGo to next message
Ian Collins  is currently offline Ian Collins
Messages: 227
Registered: July 2007
Senior Member
deadguysfrom@gmail.com wrote:
> Ive got two classes in the same class hierarchy, and I want to find
> their common ancestor. Any idea how to do this?
>
> class A {};
> class B : public A {};
> class C : public B {};
> class D : public B {};
>
> I have pointers to C and D, I want pointers to B.
>
int main()
{
D* d = new D;

B* b = d;
}

--
Ian Collins.
Re: cast classes to common ancestor [message #17373 is a reply to message #17371 ] Sat, 06 October 2007 22:44 Go to previous messageGo to next message
alfps  is currently offline alfps
Messages: 315
Registered: July 2007
Senior Member
* deadguysfrom@gmail.com:
> Ive got two classes in the same class hierarchy, and I want to find
> their common ancestor. Any idea how to do this?
>
> class A {};
> class B : public A {};
> class C : public B {};
> class D : public B {};
>
> I have pointers to C and D, I want pointers to B.

See the reply by Ian Collins else-thread.

If your enquiry is of a more academic, theoretical nature:

You can check whether the classes /have/ a common ancestor by using
static_cast, possibly combined with SFINAE.

You can go the opposite way, finding a pointer to the complete object
(of the most derived class), by using dynamic_cast<void*>, provided the
pointer you have is a pointer to an object of polymorphic class. This
is sometimes useful, e.g. for hashing. But it doesn't tell you what the
most derived class is, except you can get a run-time description.

You can not enumerate the class hierarchy by means of only language and
standard library functionality.

Cheers, & hth.,

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Re: cast classes to common ancestor [message #17374 is a reply to message #17373 ] Sat, 06 October 2007 23:15 Go to previous messageGo to next message
Kai-Uwe Bux  is currently offline Kai-Uwe Bux
Messages: 138
Registered: July 2007
Senior Member
Alf P. Steinbach wrote:

> * deadguysfrom@gmail.com:
>> Ive got two classes in the same class hierarchy, and I want to find
>> their common ancestor. Any idea how to do this?
>>
>> class A {};
>> class B : public A {};
>> class C : public B {};
>> class D : public B {};
>>
>> I have pointers to C and D, I want pointers to B.
>
> See the reply by Ian Collins else-thread.
>
> If your enquiry is of a more academic, theoretical nature:
>
> You can check whether the classes /have/ a common ancestor by using
> static_cast, possibly combined with SFINAE.

Since it sounded like a nice template exercise, I just tried to do that,
i.e., I tried to whip up a template

template < typename A, typename B >
class have_common_base {

// some SFINAE magic

public:

static bool const value =
// some more magic

};

so that have_common_base<A,B>::value would be true if and only if A and B
are derived from some common base class.

I failed, and your hint didn't quite cut it for me :-(

How would you do it?

[snip]


Best

Kai-Uwe Bux
Re: cast classes to common ancestor [message #17375 is a reply to message #17374 ] Sun, 07 October 2007 00:13 Go to previous message
alfps  is currently offline alfps
Messages: 315
Registered: July 2007
Senior Member
* Kai-Uwe Bux:
> Alf P. Steinbach wrote:
>
>> * deadguysfrom@gmail.com:
>>> Ive got two classes in the same class hierarchy, and I want to find
>>> their common ancestor. Any idea how to do this?
>>>
>>> class A {};
>>> class B : public A {};
>>> class C : public B {};
>>> class D : public B {};
>>>
>>> I have pointers to C and D, I want pointers to B.
>> See the reply by Ian Collins else-thread.
>>
>> If your enquiry is of a more academic, theoretical nature:
>>
>> You can check whether the classes /have/ a common ancestor by using
>> static_cast, possibly combined with SFINAE.
>
> Since it sounded like a nice template exercise, I just tried to do that,
> i.e., I tried to whip up a template
>
> template < typename A, typename B >
> class have_common_base {
>
> // some SFINAE magic
>
> public:
>
> static bool const value =
> // some more magic
>
> };
>
> so that have_common_base<A,B>::value would be true if and only if A and B
> are derived from some common base class.
>
> I failed, and your hint didn't quite cut it for me :-(
>
> How would you do it?

Uh, that was stupid of me. Doing what you tried (and what I literally
wrote) requires first finding the common ancestor class... Catch 22.

Fix:

"You can check whether the classes /have/ a given common ancestor by
using static_cast, possibly combined with SFINAE."

Like e.g.

<code>
#include <iostream>
#include <ostream>

typedef char Nope;
struct Yep{ char x[2]; };

template< typename T >
Nope matches( ... );

template< typename T >
Yep matches( T* );

enum { yepSize = sizeof( Yep ), nopeSize = sizeof( Nope ) };

template< typename Derived, typename Base >
bool hasBase(){ return sizeof( matches<Base>( static_cast<Derived*>(0) )
) == yepSize; }

template< typename A, typename B, typename Base >
bool haveCommonBase() { return hasBase<A, Base>() && hasBase<B, Base>(); };

struct Base {};
struct A: Base {};
struct B: Base {};

struct X {};
struct Y {};

int main()
{
using namespace std;
cout << haveCommonBase<A, B, Base>() << endl;
cout << haveCommonBase<X, Y, Base>() << endl;
}
</code>

Here 'hasBase' can yield false positives, for Base = void. Instead one
may use the more elaborate Boost checks.

Cheers,

- Alf (impreftc, and rowing energetically ;-) )

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Previous Topic:c++ tips
Next Topic:template question: preallocation for the underlying deque in user-defined queue
Goto Forum:
  


Current Time: Fri May 16 02:40:49 EDT 2008

Total time taken to generate the page: 0.11537 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 2.7.7.
Copyright ©2001-2007 FUD Forum Bulletin Board Software