4

I just run to this issue, and know from the C++ standard define it as following (emphasize mine)

An additional access check beyond those described earlier in Clause 11 is applied when a non-static data member or non-static member function is a protected member of its naming class (11.2)115 As described earlier, access to a protected member is granted because the reference occurs in a friend or member of some class C. If the access is to form a pointer to member (5.3.1), the nested-name-specifier shall denote C or a class derived from C. All other accesses involve a (possibly implicit) object expression (5.2.5). In this case, the class of the object expression shall be C or a class derived from C.

Code snippet:

class Base
{
protected: 
    int i;
};

class Derived : public Base
{
public:
    // I cannot define it as void memfunc(Derived* obj) because of signature requirement.
    void memfunc(Base* obj) 
    {
       obj->i = 0;  // ERROR, cannot access private member via Base*
       Derived* dobj = (Derived*)(obj);
       dobj->i = 0; // OK
    }
};

So what's the reason for this check? Why C++ standard bother to limit access protected member via base class pointer?

Not Duplicate to: Accessing protected members in a derived class, I want to ask for the reason to prohibit it in standard.

Community
  • 1
  • 1
ZijingWu
  • 3,350
  • 3
  • 25
  • 40

1 Answers1

6

Just because you derive from a Base doesn't mean you should be allowed to access protected member of any other class deriving from Base. Imagine a class Derived2 provided by a library which inherits from Base. This way you'll be able to get a base object of Derived2 and do whatever you want with it in the code of Derived.

So basically the standard ensures that you only modify protected members that you inherited and not mess with the integrity of unrelated siblings classes.

hawk
  • 1,827
  • 2
  • 14
  • 28
  • Note that the "workaround" in the question (casting to `Derived`) is Undefined Behavior when `obj` actually pointed to a `Derived2`. And you can't do a `dynamic_cast` since `Base` isn't polymorphic. – MSalters Nov 06 '13 at 08:55