Method Safety Levels (public vs. protected vs. private)

This topic is slightly confusing. The default access right is private in a class. For struct it is always public.

  1. Public: called anywhere
    1. The client’s interface
  2. Protected: you can only access it from a derived class
  3. Private: only used inside the class itself
    1. This has the secret implementation details

Access rights are not the same as visibility!

Private parts are visible in children (children can even redefine inherited private methods!); children just can’t use/call inherited private parts.

  • This is kind of confusing, but basically “visibility” means that the children are aware of the private parts of the parent, but cannot access get them.

Some things I learned that confused me

  1. Derived classes can’t call protected methods from parent classes?

Ohhh I finally get it, this is one of the peculiarities of Polymorphism!

class Base {  
	protected:
	    void somethingProtected() { }
};
 
class Derived : public Base {
public:
    void somethingDerived() {
        Base b;
        b.somethingProtected();    // This does NOT compile
        somethingProtected();      // this is fine
    }
};
 
int main() {
    Derived d;
    d.somethingDerived(); // Error as well
    return 0;
}

Why is this happening?

Even though somethingProtected() is a protected function, you cannot access protected members from objects of base type. You MUST access them from objects of the same derived type.

There are 3 ways to access protected members:

  1. pointer->member syntax
  2. reference.member or
  3. object.member syntax

where pointer/reference/object refers to the same derived class being called. StackOverflow

So something like this also wouldn’t work, because b is a base class, but other syntaxes do:

void Derived::somethingDerived()
{
    Base *b = this;
    b->somethingProtected();    // ERROR
    this->somethingProtected(); // OK
	// OK (implicitly calls this->somethingProtected());
    somethingProtected(); 
 
	// OK, pointer->member syntax
    Derived *b = this; b->somethingProtected();    
	// OK, reference.member
    Derived &d = *this; d.somethingProtected();    
	// OK, object.member syntax
    Derived c; c.somethingProtected();    
}

but with a friend, this would be allowed!! See friend (C++).

This is still super confusing, so I think the best way to get over this confusion is to consult the official https://cplusplus.com/doc/tutorial/inheritance/ page.