Topic: dynamic_cast to intermediate level class of A-B-C-D derivation
Author: NoSpam <nospam@nospam.com>
Date: Sun, 17 Dec 2000 14:55:17 GMT Raw View
In A-B-C-D derivation, all public, except D having protected
inheritance from C (which is a friend of D), others public, should not a
C function having access to protected inheritance be able to use
dynamic_cast to get a C pointer to an actual D, particularly since it
can dynamically cast down to D and then up to C? Otherwise, C must know
about derived classes in order to get a pointer of its own type? This
seems peculiar, so I was wondering what the behavior should be,
according to the standard, and whether the standard should specify that
code having accessibility should be able to get non-null pointers form
dynamic_cast, and not need to use the less safe static_cast or the kluge
of knowing about lower-level derivation ?
Also, should not C, being a friend of D, be able to access private
elements of C through a D pointer, since that pointer can be transformed
up to a C pointer without even needing an explicit cast?
Thanks in advance,
David
P.S. To decipher the anti-spam address at the end of this sentence,
cycle each letter down one in the alphabet and change the two
underscores to at-sign and period, respectively, from the following:
dqmvtqmvt_bum-joum_dpn.
Output:
pB = 00000000
pC = 00000000
pD = 0012FF1C
pC = 0012FF1C
pB = 00000000
pC = 00000000
pD = 0012FF1C
pC = 0012FF1C
Code:
#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();
public:
static void testCast();
};
class D: protected C
{
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 ;
}
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. ]
Author: bonnard@clipper.ens.fr (Valentin Bonnard)
Date: Mon, 18 Dec 2000 17:54:43 GMT Raw View
NoSpam wrote:
> In A-B-C-D derivation, all public, except D having protected
> inheritance from C (which is a friend of D), others public, should not a
> C function having access to protected inheritance be able to use
> dynamic_cast to get a C pointer to an actual D, particularly since it
> can dynamically cast down to D and then up to C? Otherwise, C must know
> about derived classes in order to get a pointer of its own type? This
> seems peculiar, so I was wondering what the behavior should be,
> according to the standard, and whether the standard should specify that
> code having accessibility should be able to get non-null pointers form
> dynamic_cast, and not need to use the less safe static_cast or the kluge
> of knowing about lower-level derivation ?
>
> Also, should not C, being a friend of D, be able to access private
> elements of C through a D pointer, since that pointer can be transformed
> up to a C pointer without even needing an explicit cast?
dynamic_cast isn't a clever as you think: it is context-
independent, it doesn't have macro behaviour !
Here the full text of 5.2.7/8 (emphasis mine):
The run-time check logically executes as follows:
If, in the most derived object pointed (referred) to by v,
v points (refers) to a PUBLIC base class sub-object of a
T object, and if only one object of type T is derived from
the sub-object pointed (referred) to by v, the result is a
pointer (an lvalue referring) to that T object.
Otherwise, if v points (refers) to a PUBLIC base class
sub-object of the most derived object, and the type of
the most derived object has an unambiguous public
base class of type T, the result is a pointer (an lvalue
referring) to the T sub-object of the most derived
object.
Otherwise, the run-time check fails.
dynamic_cast is all about publicness, no accessibility.
Doing it the other way would be more difficult for the
poor compiler writer.
--
Valentin Bonnard
---
[ 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. ]