简体   繁体   中英

Why can't I access protected members of base class in derived instances using protected/private inheritance?

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;
}

Since Derived inherits from Base protected ly, all public members of Base are protected in Derived . This means, outside of Derived (eg 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]).

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)

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM