为什么这个派生类的定义是非法的?

时间:2018-03-01 23:32:49

标签: c++ class c++11 inheritance

为什么派生类Derived_from_Private是非法的? 我注意到成员函数有一个Base的引用,但为什么它不能引用Base类?

class Base {
public:
  void pub_mem(); // public member
protected:
  int prot_mem; // protected member
private:
  char priv_mem; // private member
};

struct Pub_Derv : public Base {
  // legal
  void memfcn(Base &b) { b = *this; }
};

struct Priv_Derv : private Base {
  // legal
  void memfcn(Base &b) { b = *this; }
};

struct Prot_Derv : protected Base {
  // legal
  void memfcn(Base &b) { b = *this; }
};

struct Derived_from_Public : public Pub_Derv {
  // legal
  void memfcn(Base &b) { b = *this; }
};

struct Derived_from_Private : public Priv_Derv {
  // illegal
  void memfcn(Base &b) { b = *this; }
};

struct Derived_from_Protected : public Prot_Derv {
  // legal
  void memfcn(Base &b) { b = *this; }
};

4 个答案:

答案 0 :(得分:3)

表达式

b = *this;

需要调用从*this到类型Base的左值的隐式转换,以便调用隐式声明的Base::operator=(const Base&)。此转换通过路径Derived_from_Private -> Priv_Derv -> Base。由于Priv_DervBase作为私人基础,Derived_from_Private无法访问第二个链接。

答案 1 :(得分:2)

Priv_Derv私下继承Base。这意味着只有类本身知道它也是Base,只有Priv_Derv的成员函数才能使用Base的成员。

您稍后可以Derived_from_Private公开继承Priv_Derv。这是合法的。但不幸的是,由于以前的私有继承,它好像Derived_from_Private没有Base作为基类。

因此,您的成员函数将无法编译:

    void memfcn(Base &b) { b = *this; }

*thisDerived_from_Private,但将其转换为Base类是非法的,因为由于私有继承而与该类没有已知关系。

答案 2 :(得分:0)

继承可以同时提供子类型结构扩展

当您从基类私下继承时,您没有子类型,只有结构扩展。然后(在你有问题的情况下)当你写b = *this a *this {<1}} 时,因为你已经使用了它的私有继承。

通常使用私有继承(这并不意味着它是一个好习惯)来轻松构建非常简单的组合(具有基础,但基础)

答案 3 :(得分:0)

类的名称作为公共成员插入到自身的范围中。这就是所谓的LocalPdfManager。派生类BaseDerived_from_Private的名称查找将找到其注入类名而不是正常名。由于Base的注入班级名称被视为Base的公开成员,因此被视为私人号码Priv_Derv,因此Derived_from_Private无法访问该class A { }; class B : private A { }; class C : public B { A* p; // error: injected-class-name A is inaccessible ::A* q; // OK };

引自injected-class-name

  

[注意:在派生类中,基类名称的查找将找到inject-name-name而不是声明它的作用域中基类的名称。 inject-name的名称可能比声明它的作用域中的基类名称更不易访问。 - 结束记录] [示例:

system2()
     

- 结束示例]