Sign in to follow this  
Zouflain

(C++) trouble with polymorphic access violations

Recommended Posts

More and more I'm finding myself snagged on very simple problems... Anyway, I have two classes - we'll say top and bottom, such that bottom is a derived class from top. Top contains private and public members, and bottom is supposed to have free access to them. I need to be able to freely use class polymorphism (which I've never had problems with before...) and while using such polymorphism, continue to access members from Top. Here's what I have looks like:
class top{
  public:
    //some members
  protected:
    top* parent;//important later
    int foo;//later
    //more members
};
class bottom : public top{
  public:
    void bar(void);//again, later
    //some others
  private:
    //not many
};
This, so far, is a no brainer. The problem is I'm getting an access violation error in bottom::bar when using parent->foo.
void bottom::bar(){
    int n = foo+parent->foo;//error C2248: 'top::foo' : cannot access protected member declared in class 'top'
}
The exact reason for this construction is this: I'm writing a simple GUI class, and certain types of windows need to refer directly to their parent's value (namely "child" windows like buttons) in order reposition themselves to be at the parents location + offset. They don't, however, know what their parent is except that it is a derived class from the GUI base class. So, for instance, a menu can have buttons, but then so can a text box. I'd appreciate any explanation as to what I'm doing wrong... I feel I have significant holes in my C++ knowledge, probably because I had to teach myself from google =/

Share this post


Link to post
Share on other sites
If you split your code over onto two lines, like this:
void bottom::bar(){
int n = foo;
n = n + parent->foo;//error C2248: 'top::foo' : cannot access protected member declared in class 'top'
}

...then you can see that accessing the first foo is fine (this->foo), but accessing the second foo is what causes the error (parent->foo).
This shows us that bottom can access it's foo variable (inherited from top), but it isn't allowed to access it's parent foo variable.

Another experiment:
void bottom::bar(){
top* self_as_top = this;
bottom* self_as_bottom = this;
int n1 = self_as_bottom->foo;//no error
int n2 = self_as_top->foo;//error C2248: 'top::foo' : cannot access protected member declared in class 'top'
}
This shows us that bottom can't even access it's own foo variable, if it uses a "top*" to do the accessing.

So from these tests, we can deduce that protected allows the bottom class to access top's variables, but only if we're sure that the particular top object being accessed really is a bottom object.

In your case, parent might be something other than a bottom, so bottom isn't allowed to look at it's protected data.


You can work around this by adding a public accessor method:
class top{
public:
int Foo() const { return foo; }
...
};
...
void bottom::bar(){
int n = foo+parent->Foo();
}

Share this post


Link to post
Share on other sites
Quote:
MSDN
Protected members that are not declared as static are accessible to friends and member functions in a derived class only through a pointer to, reference to, or object of the derived class.

In other words, the protected access modifier is distinct from declaring the derived class as a special kind of "friend" that can access protected data.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this