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

问题描述 投票:3回答:4

为什么派生类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; }
};
c++ class c++11 inheritance
4个回答
3
投票

表达方式

b = *this;

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


2
投票

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

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

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

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

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


0
投票

继承可以提供子类型和结构扩展。

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

通常使用私有继承(这并不意味着它是一种好的做法)来轻松构造非常简单的组合(有一个基础,但不是一个基础)。


0
投票

类的名称作为公共成员插入到自身的范围中。这就是所谓的injected-class-name。派生类BaseDerived_from_Private的名称查找将找到它的注入类名而不是正常名。因为Base的注入类名被视为Base的公共成员,因此被视为Priv_Derv的私人号码,它在Derived_from_Private中是不可访问的。

来自qazxsw poi的行情:

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

[class.access.spec] paragraph 5

- 结束例子]

© www.soinside.com 2019 - 2024. All rights reserved.