Topic: Upcasting


Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/09/22
Raw View
Siemel Naran wrote:

[...]

> struct Something
> {
>      void func(const Derived& d)
>      {
>           d.num(); // error (?)
>           const Base& b=d; // ok
>           b.num(); // ok
>      }
> };
>
> I'm not sure about the line "error (?)" above.  I think it should be
> an error, because it must in general be assumed that class Derived
> has defined a function num() in its own private or protected space.
> g++ 2.7.2.3 doesn't give an error though.

Since to be able to even compile d.num(), you must have a definition
of class Derived, there is nothing that must be assumed about d - the
definition of class Derived is completely known, so the compiler can
just look at it to check for a protected or private function num()
there.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Brian Rasmussen <none@none.dk>
Date: 1998/09/18
Raw View
I have convinced myself that the following code is standard C++:

class a {
};

class b : protected /* @ */ a {
};

class c: protected b {
 void mfunc( void );
};


void c::mfunc( void )
{
 b* pb = new b;
 a* pa = pb;
}

I mean as long as "a" is a protected base class ( @ ), then are
memberfunctions in classes derived from "b" permited to upcast pointers
from b* to a*.

What is wrong, my compiler "MS devel. studie 97" errors:
" 'type cast' : conversion from 'class b *' to 'class a *' exists, but
is inaccessible."
It insists that "@" must be public.

Is the code not std C++ compatible, or is "MS devel. studie 97" not std.
C++ compatible?

URSULA



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Alfred Kellner" <alfkellner@magnet.at>
Date: 1998/09/19
Raw View
Brian Rasmussen <none@none.dk> wrote
>
> I have convinced myself that the following code is standard C++:

I couldn't do the same.

> class a { };
> class b : protected /* @ */ a { };
> class c: protected b {
>  void mfunc( void );
> };
>
> void c::mfunc( void ) {
> b* pb = new b;
> a* pa = pb; // error
> }
> I mean as long as "a" is a protected base class ( @ ), then are
> memberfunctions in classes derived from "b" permited to upcast pointers
> from b* to a*.

b*, in this context, could really point to a different dynamic type
(other than class c,as it does), like
 class DD: protected b {};
So, what you demand, is:
 'class c' gets access to a protected base 'class a' of DD,
 if it can get hold of a pointer to DD:b.
I guess, you wouldn't want to allow THAT ?
See sample below.
 --ALfred
<code>
class A {};
class B : protected /* @ */ A {
protected:
 static A * B_convert_to_A( B * pB ) {
  // conversion to A* allowed
  return pB; }
};
class C: protected B {
 void mfunc( B * pB );
public: void foo() {
  mfunc(0);
 }
 void use_A_of( B * pB ) {
  mfunc( pB );
 }
};
class DD: protected B {
public: void grant_B( C * pC )
 {
  B * B_of_DD =  this ;
  pC->use_A_of( B_of_DD );
 }
};
void C::mfunc( B * pB )
{ // pB maybe of dynamic type DD * !
 A * pA; // = pB; // here ERROR, disallowed pB_of_DD to pA
 pA = B_convert_to_A( pB );
 pA = this; // OK !
 pB = this; // OK !

 static DD * pDD;
 if( !pDD ) {
  pDD = new DD;
  pDD->grant_B( this ); // mfunc recursive
 }
}
void foo(){
 C c;
 c.foo();
}
</code>



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/09/21
Raw View
Brian Rasmussen wrote:
>
> I have convinced myself that the following code is standard C++:
>
> class a {
> };
>
> class b : protected /* @ */ a {
> };
>
> class c: protected b {
>  void mfunc( void );
> };
>
> void c::mfunc( void )
> {
>  b* pb = new b;
>  a* pa = pb;
> }
>
> I mean as long as "a" is a protected base class ( @ ), then are
> memberfunctions in classes derived from "b" permited to upcast
> pointers from b* to a*.

You can only access protected members of "this", not of other objects
accessed through pointer variables. See section 11.5 [class.protected]
of the last draft of the standard.

--

Ciao,
Paul
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
Date: 1998/09/21
Raw View
On 18 Sep 1998 16:11:08 GMT, Brian Rasmussen <none@none.dk> wrote:

>I have convinced myself that the following code is standard C++:

No.

The protected inheritance in B:A means that an object of type
B can see the public/protected parts of the A part of another B
object.  By contrast, a B object cannot see the public/protected
parts of any A object.

The protected inheritance in C:B means that an object of type
C can see the public/protected parts of the B part of another C
object.  By contrast, a C object cannot see the public/protected
parts of any B object.

This rule is the most safe for encapsulation.

>class a {
>};
>
>class b : protected /* @ */ a {
>};
>
>class c: protected b {
> void mfunc( void );
>};
>
>
>void c::mfunc( void )
>{
> b* pb = new b;
> a* pa = pb;
>}

-----

A related point:


struct Base
{
     friend class Something;
     protected:
          int num() const;
};

struct Derived : public Base
{
     void func(const Derived& d)
     {
          this->num(); // ok
          d.num(); // ok
          const Base& b=d; // ok
          b.num(); // error
     }
};

struct Something
{
     void func(const Derived& d)
     {
          d.num(); // error (?)
          const Base& b=d; // ok
          b.num(); // ok
     }
};


I'm not sure about the line "error (?)" above.  I think it should be
an error, because it must in general be assumed that class Derived
has defined a function num() in its own private or protected space.
g++ 2.7.2.3 doesn't give an error though.



--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]