Bug 37112 - nested inherited class can't access protected members of base class
Summary: nested inherited class can't access protected members of base class
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.2.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-08-13 14:08 UTC by Steven
Modified: 2008-08-13 15:57 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Steven 2008-08-13 14:08:04 UTC
The following code fails to compile:

class A {
protected:
    int i;
};

class B {
    class C : public A {
    public:
        void foo(A a) { 
            a.i = 1;
        }
    };
};

int main()
{
    
}

nest2.cpp: In member function 'void B::C::foo(A)':
nest2.cpp:3: error: 'int A::i' is protected
nest2.cpp:10: error: within this context

I can't find anything in the standard that says this should be invalid, but perhaps I missed it. Thanks for your time and efforts.
Comment 1 Chris Fairles 2008-08-13 15:32:19 UTC
You're simply trying to access a protected member variable which is not allowed. It doesn't matter if you try to access it from a member function of a sub-object of A; if you have an object of type A, and it has a protected member var i, you cannot access it directly. If foo() took a type C, or only tried to access "i" (the protected member var of A from which C inherits) as opposed to a.i, then it will compile as expected.

HTH,

Chris


Comment 2 Steven 2008-08-13 15:57:55 UTC
Thanks for your reply. I think I would have seen this had I tried testing it without the nesting. I tried to compile the following code:

class A {
protected:
    int i;
};

class B : public A {
public:
    void foo(A *a) {
        a->i = 1;
    }
};

And it also did not work. However, if I change the parameter of foo() to a B, then it works. I guess this is to prevent a child class from modifying an instance of type parent, and not type child. It's ok to modify something protected if it's your type, but by making the parameter the type of the parent you can't be sure it's the same child type. (Well, you can with dynamic_cast, but it wouldn't make sense to allow it.) 

Thanks for the food for thought. I'll cancel the bug.