为什么派生类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; }
};
表达方式
b = *this;
需要调用从*this
到类型为Base
的左值的隐式转换,以便调用隐式声明的Base::operator=(const Base&)
。这种转换通过路径Derived_from_Private -> Priv_Derv -> Base
。由于Priv_Derv
将Base
作为私人基地,Derived_from_Private
无法访问第二个链接。
Priv_Derv
私下继承Base
。这意味着只有类本身知道它也是Base
,只有Priv_Derv
的成员函数才能使用Base
的成员。
你可以稍后让Derived_from_Private
从Priv_Derv
公开继承。这是合法的。但不幸的是,由于前私人继承,就好像Derived_from_Private
没有Base
作为基类。
因此,您的成员函数将无法编译:
void memfcn(Base &b) { b = *this; }
*this
是一个Derived_from_Private
,但将它转换为Base
类是非法的,因为由于私有继承而与该类没有已知的关系。
继承可以提供子类型和结构扩展。
当您从基类私有地继承时,您没有子类型,只有结构扩展。然后(在你有问题的情况下)当你写b = *this
alas *this
不是Base
类型,因为你已经使用了它的私有继承。
通常使用私有继承(这并不意味着它是一种好的做法)来轻松构造非常简单的组合(有一个基础,但不是一个基础)。
类的名称作为公共成员插入到自身的范围中。这就是所谓的injected-class-name。派生类Base
中Derived_from_Private
的名称查找将找到它的注入类名而不是正常名。因为Base
的注入类名被视为Base
的公共成员,因此被视为Priv_Derv
的私人号码,它在Derived_from_Private
中是不可访问的。
来自qazxsw poi的行情:
[注意:在派生类中,基类名称的查找将在声明它的作用域中找到inject-class-name而不是基类的名称。 inject-name的名称可能比声明它的作用域中的基类名称更不易访问。 - 尾注] [示例:
[class.access.spec] paragraph 5- 结束例子]