derived class access to base class protected members

Started by
14 comments, last by Scythen 19 years, 2 months ago
I don't even understand why this is not working in the first place! As far as I'm concerned the keyword protected implies that a class which is directly derived from the class in which the member is defined can do with the member whatever the hell it wants, regardless of whether it's 'bad design' or not. If the compiler doesn't support that then it's a crap compiler, period!

P.S. Hmmm, maybe I was a little too quick with my comment. I'm not sure what the standard has to say on trying to access protected members of an instance of the base class rather than on an instance of the derived class.
Advertisement
Quote:Original post by MaulingMonkey
Curse my inability to read late at night. Appologies D:
Yeah, it's getting pretty late here as well [smile]...it also doesn't help that no matter how it's done it's gonna be ugly, so the OP asking for a non-ugly solution is a little futile (someone's going to come along with an elegant solution now and prove me wrong [looksaround]...)

Quote:Original post by Red Ant
I don't even understand why this is not working in the first place! As far as I'm concerned the keyword protected implies that a class which is directly derived from the class in which the member is defined can do with the member whatever the hell it wants, regardless of whether it's 'bad design' or not. If the compiler doesn't support that then it's a crap compiler, period!
It's because if you have three classes class A, class B : public A, and class C : public A you can upcast a C to and A. Should B's member functions then be able to operate on the internals of A? I don't think so, and obviously neither do some compiler writers [smile] It is a little weird though, 'cause you'd think from the descriptions of what the access specifiers do that you'd be able to do this, and it's not very well documented that you can't (at least, I couldn't find many references to it when I searched before)...
Yeah, you're right, I just checked. Stroustrup demonstrates in 15.3.1


class Buffer {protected:    char a[ 128 ];    // ...};class Linked_buffer : public Buffer { /* ... */ };class Cyclic_buffer_ public Buffer {    // ...    void f( Linked_buffer* p ) {        // ...        a[ 0 ] = 0;     // ok: access to cyclic_buffer's own protected member        p->a[ 0 ] = 0;  // error: access to protected member of different type    }};




P.S. On second thought, I would still think that it would be okay to do this in class Linked_buffer:

    void g( Buffer& b ) {        b.a[ 0 ] = 0;    }


but I guess not.
Also see Bjarne's thoughts on protected member data.
Quote:
Five years or so later, Mark banned the use of protected data
members in [the software product called] Interviews because
they had become a source of bugs:
``novice users poking where they shouldn't in ways that they ought
to have known better than.'' They also seriously complicate
maintenance: ``now it would be nice to change this, do you think
someone out there might have used it?'' Barbara Liskov's OOPSLA
keynote gives a detailed explanation of the theoretical and
practical problems with access control based on the `protected'
notion. In my experience, there have always been alternatives
to placing significant amounts of information in a common base
class for derived classes to use directly. In fact, one of my
concerns about `protected' is exactly that it makes it too easy
to use a common base the way one might sloppily have used global
data.

Fortunately, you don't have to use protected data in C++;
`private' is the default in classes and is usually the better
choice. Note that none of these objections are significant for
protected member functions. I still consider `protected'
a fine way of specifying operations for use in derived classes.
Well, just read up on it.
I agree with Stroustrup about the danger of protected members.

In my example I used a member variable but in reality I am only using member functions.

It looks like if I want to use my current design I'll have to make all derived classes friends of the base class[crying]
What really sucks is that all those classes will have access to private data as well[bawling]

petewood
Quote:This isn't a good design and would have to be something very specific to justify doing it.


The design issue may have something to do with the whole problem.
This is not my exact design but I think it shows what I'm trying to do.

There is a base class with virtual Attach and Detach member functions, these manage a parent relationship. They are protected because only the base class and derived classes are allowed to change the parent relationship.
All of the member data is private.
There are also public virtual AddChild and RemoveChild functions which have base class references as their arguments.

So:
virtual void DerivedClass::AddChild(BaseClass &baseClass){    // Do derived class stuff and don’t call the base class impl because     // it does stuff that is not valid here    // use the protected member functions to modify the parent relationship    baseClass.Detach();    // remove any parent    baseClass.Attach(this);// add this as the new parent}


I’m going to rethink my design; there is probably a better way to do this...
Just read that article about making virtual functions private by default mentioned by petewood.
Very interesting, I'll need to put that to use.

This topic is closed to new replies.

Advertisement