Topic: dynamic_cast to C of hierarchy D protected: C public B: public A
Author: nospam@nospam.com
Date: Mon, 18 Dec 2000 17:51:57 GMT Raw View
Given the code below, in which functions having accessibility to all
classes attempt to use dynamic_cast<C*> to obtain a C pointer from an A
pointer to an object that is actually a D, and get a null pointer, should
the result be different according to the standard, particularly since a
down-cast to D and then an (implicit) up-cast to C does work?
The situation (in its original form) comes about as a result of using
ostream/streambuf, in which a derived stream tries to check that rdbuf()
returns a pointer to a C, but in which the actual C is really a D derived
(protected); the down-caster is a friend of both the C and D classes.
The compiler used was Visual C++ 6.0, but I think gcc gives the same
result.
If the standard really does specify this behavior, should that standard
be changed, since the alternative is something of a kluge, e.g. making C
aware of D, or something similar?
Thanks in advance,
David
P.S. My email address can be obtained by changing the anti-spam address at
the end of this sentence as follows: cycle each letter back one in the
alphabet and change the underscores to at-sign and period, respectively:
dqmvtqmvt_bum-joum_dpn.
Output:
pB = 00000000
pC = 00000000
pD = 0012FF14
pC = 0012FF14
pB = 00000000
pC = 00000000
pD = 0012FF14
pC = 0012FF14
Source code of simplified example:
#include <iostream>
using namespace std ;
class C;
class A
{
public:
inline virtual ~A(){}
friend void DynCastTest();
friend class C ;
friend class D ;
friend class B ;
};
class B: public A
{
friend void DynCastTest();
friend class C ;
friend class B ;
friend class D ;
};
class C: public B
{
friend class D ;
friend class B ;
friend class A ;
friend void DynCastTest();
int m_intC ;
public:
static void testCast();
};
class D: protected C
{
int m_intD ;
public:
// ~D(){}
friend void DynCastTest();
friend void C::testCast();
friend class C ;
friend class B ;
friend class A ;
};
void C::testCast()
{
D d1 ;
A * pA = &d1 ;
B * pB = dynamic_cast< B *>( pA );
C * pC = dynamic_cast< C *>( pA );
D * pD = dynamic_cast< D *>( pA );
cout << "pB = " << (void*)pB << endl ;
cout << "pC = " << (void*)pC << endl ;
cout << "pD = " << (void*)pD << endl ;
pC = pD ;
cout << "pC = " << (void*)pC << endl ;
pC->m_intC = 123 ;
}
void DynCastTest()
{
D d1 ;
A * pA = &d1 ;
B * pB = dynamic_cast< B *>( pA );
C * pC = dynamic_cast< C *>( pA );
D * pD = dynamic_cast< D *>( pA );
cout << "pB = " << (void*)pB << endl ;
cout << "pC = " << (void*)pC << endl ;
cout << "pD = " << (void*)pD << endl ;
pC = pD ;
cout << "pC = " << (void*)pC << endl ;
}
int main()
{
DynCastTest();
C::testCast();
return 0 ;
}
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]