Search code examples
c++access-specifier

c++ access-specifier understanding


I have encountered the following response in a thread :

Protected members can be accessed from derived classes. Private ones can't.

class Base {

private: 
  int MyPrivateInt;
protected: 
  int MyProtectedInt;
public:
  int MyPublicInt;
};

class Derived : Base
{
public:
  int foo1()  { return MyPrivateInt;} // Won't compile!
  int foo2()  { return MyProtectedInt;} // OK  
  int foo3()  { return MyPublicInt;} // OK
};

class Unrelated 
{
private:
  Base B;
public:
  int foo1()  { return B.MyPrivateInt;} // Won't compile!
  int foo2()  { return B.MyProtectedInt;} // Won't compile
  int foo3()  { return B.MyPublicInt;} // OK
};

...

1) my question is: I have read : "A class derivation list names one or more base classes and has the form:

class derived-class: access-specifier base-class

Where access-specifier is one of public, protected, or private, and base-class is the name of a previously defined class. If the access-specifier is not used, then it is private by default. " and "Private Inheritance: When deriving from a private base class, public and protected members of the base class become private members of the derived class.

"

SO...in our example class Derived : Base is equivalent to class Derived : private Base because no access-specifier has been defined, yet the code works as the writer said, so what am i missing?- i thought that Base class for the class Derived access-specifier is private therefore public and protected members of Base should be private for class Derived and can't be accessed... thanks!


Solution

  • Its a similar kind of idea. Rather than applying to which members of the class you can access, it applies to which base classes you can access.

    class A
    {
    public:
        void f();
    };
    
    
    
    class B : public A
    {
    public:
        void g()
        {
            f(); // OK
            A *a = this; // OK
        }
    };
    class B2 : public B
    {
    public:
        void h()
        {
            f(); //OK
            A *a = this; // OK
        };
    };
    B b;
    A& ba = b;
    
    
    class C : protected A
    {
    public:
        void g()
        {
            f(); // OK, can access protected base
            A *a = this; // OK, can access protected base
        }
    };
    class C2 : public C
    {
    public:
        void h()
        {
            f(); // OK, can access protected base
            A *a = this; // OK, can access protected base
        };
    };
    C c;
    c.f(); // Not OK, allthough A::f() is public, the inheritance is protected.
    A& ca = c; // Not OK, inheritence is protected.
    
    
    
    
    class D : private A
    {
    public:
        void g()
        {
            f(); // OK because A is a base of D
            A *a = this;
        }
    };
    class D2 : public D
    {
    public:
        void h()
        {
            f(); //Not OK, A is inherited with private in D
            A *a = this; //Not OK
        };
    };
    D d;
    d.f(); // Not OK, allthough A::f() is public, the inheritance is private.
    D& da = d; // Not OK, inheritence is private.