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.     ]