0
votes

I thought that protected members of a Base class can be accessed by instances of the Derived class (or any classes that derive from the Derived class, given that they inherit from the latter publicly).

But I get an error when attempting to do just that in the following listings. So what am I missing?

class Base{
private:
  virtual void f(){cout << "f of Base" << endl;}

public:
  virtual ~Base(){}
  virtual void g(){this->f();}
  virtual void h(){cout << "h of Base "; this->f();}
};

class Derived: protected Base{
public:
  virtual ~Derived(){}
  virtual void f(){cout << "f of Derived" << endl;}
private:
  virtual void h(){cout << "h of Derived "; this->f();}
};

int main(){
  Base *base = new Base();
  cout << "Base" << endl;
  base->g(); //f of Base
  base->h(); //h of Base f of Base

  Derived *derived = new Derived();
  cout << "Derived" << endl;
  derived->f(); //f of Derived
  derived->g(); //this doesn't compile and I get the error "void Base::g() is inaccessible within this context". Why?
  derived->h(); //this doesn't compile given that h is private in Derived

  delete base;
  delete derived;
  return EXIT_SUCCESS;
}
3
Why are you using virtual inheritance here?Jesper Juhl
syntax error, didn't mean to include virtual in the inheritance clause. I'll fix itAnonBNR
derived->h() , you cannot access private members outside class ; in derived class the member function is declared private .Vishnu R

3 Answers

4
votes

Since Derived inherits from Base protectedly, all public members of Base are protected in Derived. This means, outside of Derived (e.g. in main), those members' name are not visible.

[class.access.base]/1

[...] If a class is declared to be a base class for another class using the protected access specifier, the public and protected members of the base class are accessible as protected members of the derived class. [...]

[class.access]/1.2

A member of a class can be

(1.2) protected; that is, its name can be used only by members and friends of the class in which it is declared, by classes derived from that class, and by their friends (see [class.protected]).

3
votes

derived->g();

can be accessed by changing inheritance to public.

derived->h();

can be accessed by changing access specifier inside derived class from private to public(still keeping inheritance as protected,since derived class pointer points to its member function)

1
votes

When you declare protected inheritance of Base by Derived as follows

class Derived: protected Base

You are basically making any public methods of the Base class protected members of the derived class. If you instead declare the inheritance as public via

class Derived: public Base

you will find you will be able to access derived->g() just fine.