【问题标题】:Why can't I access protected members of base class in derived instances using protected/private inheritance?为什么我不能使用受保护/私有继承访问派生实例中基类的受保护成员?
【发布时间】:2018-10-21 05:30:13
【问题描述】:

我认为基类的受保护成员可以被派生类(或派生自派生类的任何类,因为它们公开继承自后者)的实例访问。

但在以下列表中尝试执行此操作时出现错误。那我错过了什么?

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

【问题讨论】:

  • 为什么在这里使用虚拟继承?
  • 语法错误,并不意味着在继承子句中包含 virtual。我会解决的
  • derived->h() ,你不能访问类外的私有成员;在派生类中,成员函数被声明为私有。

标签: c++ inheritance protected


【解决方案1】:

派生->g();

可以通过将继承更改为公共来访问。

派生->h();

可以通过将派生类中的访问说明符从私有更改为公共来访问(仍然保持继承为受保护,因为派生类指针指向其成员函数)

【讨论】:

    【解决方案2】:

    当你声明protected继承BaseDerived如下

    class Derived: protected Base
    

    您基本上是在创建派生类的Baseprotected 成员的任何公共方法。如果您改为通过

    将继承声明为公共
    class Derived: public Base
    

    你会发现你可以访问derived-&gt;g()就好了。

    【讨论】:

    • 是的,已经尝试过了,效果很好,我只是忘记了我实际上是在主函数中调用 g() 的事实,因此出现了错误。还是谢谢!
    • 乐于助人 ;)
    【解决方案3】:

    由于Derived 继承自Base protectedly,所以Base 的所有公共成员都是protected 中的protected。这意味着,在Derived 之外(例如在main 中),这些成员的名字是不可见的。

    [class.access.base]/1

    [...] 如果使用protected 访问说明符将一个类声明为另一个类的基类,则基类的公共和受保护成员可以作为派生类的受保护成员访问。 [...]

    [class.access]/1.2

    一个类的成员可以是

    (1.2) 受保护;也就是说,它的名称只能由声明它的类的成员和朋友、从该类派生的类以及它们的朋友使用(参见 [class.protected])。

    【讨论】:

      猜你喜欢
      • 2013-03-05
      • 1970-01-01
      • 1970-01-01
      • 2011-03-10
      • 1970-01-01
      • 2014-08-27
      • 2018-11-27
      相关资源
      最近更新 更多