"Michael Young" <michael.young@paetec.com> wrote in message
news:83f9daa0.0309041316.77060f53@posting.google.com...
I've been trying to compile code similar to the example code below,
but I keep getting errors indicating that the function 'foo()' is not
accessible. At first, I thought this was a bug in the compiler, but
I've now tried the code against Borland C++ Builder 6.0, MS VC++ .NET,
DevC++ (GCC), and Comeau's on-line compiler, and all give me similar
diagnositic messages.
I can make the code work if I make the "protected" items "public" in
the base class. But that's really not what I want...
So, what is wrong with my code?
It breaks the access rules of C++.
I was under the impression that any
member of a class that is publicly derived from a base class should be
able to access the base class public and protected members.
Obviously, I've oversimplified it and missed something along the way
(or maybe it doesn't apply here for some reason?).
Its a very common misunderstanding. If you searched for protected in this
group you would find many other similar questions to yours.
If anyone can quote chapter and verse from the standard (preferably
with a somewhat more "human" explanation as well) that explains the
behavior, I'd greatly appreciate it!
#include <cstdlib>
//--------------------------------------------------------------------------
-
class Base
{
// public :
protected :
Base ( Base* structural_child )
: polymorphic_child_( structural_child )
{
}
virtual
void
foo ( unsigned int recurse_count ) const = 0 ;
// public :
protected :
Base* polymorphic_child_ ; // In "real" code, there is a list
// of pointers to objects, and this
// class is a hierarchical data
// structure.
} ;
//--------------------------------------------------------------------------
-
class Derived
: public Base
{
public :
Derived ( )
: Base( NULL )
{
}
protected :
virtual
void
foo ( unsigned int recurse_count ) const
{
if ( ( NULL != polymorphic_child_ ) &&
( recurse_count > 0 ) ) {
// Problem arises from following line
polymorphic_child_->foo( --recurse_count ) ;
}
}
} ;
//--------------------------------------------------------------------------
-
int
main ( int argc, char* argv[] )
{
Derived d ;
return( 0 ) ;
}
I don't know about the standard but here is Stroustrup.
"A derived class can access a base class' protected members only for objects
of its own type".
In your case the type is Derived but the pointer you are trying to access
via has type Base. Base is not of type Derived. If you declared
polymorphic_child_ as type Derived* (or any type derived from Derived) your
example would work.
Why this rule? I don't honestly know. I've seen it explained with an example
and it made sense at the time but it didn't stick in my mind. Stroustrup
just says cryptically "This prevents subtle errors that would otherwise
occur when one derived class corrupts data belonging to other derived
classes.".
Maybe try a search through the archives of this group for a better
explanation (or maybe someone reading this will oblige).
John
.