Почему я не могу получить доступ к защищенным членам базового класса в производных экземплярах, используя защищенное / частное наследование? - PullRequest
0 голосов
/ 11 мая 2018

Я думал, что к защищенным членам базового класса могут обращаться экземпляры класса Derived (или любые классы, производные от класса Derived, если они публично наследуются от последнего).

Но я получаю сообщение об ошибке при попытке сделать это в следующих списках. Так чего мне не хватает?

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 ]

0 голосов
/ 11 мая 2018

Когда вы объявляете protected наследование Base от Derived следующим образом

class Derived: protected Base

Вы в основном делаете любые открытые методы Base класса protected членов производного класса,Если вместо этого вы объявите наследство как общедоступное через

class Derived: public Base

, вы обнаружите, что сможете получить доступ к derived->g() просто отлично.

0 голосов
/ 11 мая 2018

производный-> g ();

можно получить, изменив наследование на public.

производный-> h ();

можно получить, изменив спецификатор доступа внутри производного класса с частного на общедоступный (все еще сохраняя наследование как защищенное, поскольку указатель производного класса указывает на его функцию-член)

0 голосов
/ 11 мая 2018

Поскольку Derived наследуется от Base protected ly, все открытые члены Base имеют значение protected in Derived. Это означает, что за пределами Derived (например, в main) имя этих членов не отображается.

[class.access.base]/1

[...] Если класс объявлен как базовый класс для другого класса с использованием спецификатора доступа protected, публичные и защищенные члены базового класса доступны как защищенные члены производного класса. [...]

[class.access]/1.2

Членом класса может быть

(1,2) защищено; то есть его имя может использоваться только членами и друзьями класса, в котором он объявлен, классами, производными от этого класса, и их друзьями (см. [class.protected]).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...