class B
{
public:
B() { }
public:
int num_;
};
class Son:private B //这里为private继承和protected继承对于本文要说明的问题的效果是一样的
{
public:
Son(){};
~Son(){};
Son* pson = &son;
pb = static_cast<B*>(pson); -------编译出错
B* pb = &son; -------编译出错
B &ref = son; -------编译出错
如果将这种派生类能合法地转换成base类,则可以通过base类实例来访问派生类中base类的public成员了。这明显是破坏了派生类中的base类的public成员对外的可见性了,当然不合法了。要不然的话,通过一个private或protected的派生类实例无法访问到base类的public成员,我只需要通过转换成base类就可以访问了呢。这样的话,不同类型的派生类中对基类成员的可见性的设置就毫无意义了。
{
public:
B() { }
public:
int num_;
};
class Son:private B //这里为private继承和protected继承对于本文要说明的问题的效果是一样的
{
public:
Son(){};
~Son(){};
};
Son* pson = &son;
//c++风格的类类型转换
pb = static_cast<B*>(pson); -------编译出错
//赋值兼容规则的三种形式
B* pb = &son; -------编译出错
B &ref = son; -------编译出错
而只需要将上面的class Son:private B继承改为共有继承class Son:public B,则上述出错的代码就都能正常工作了。为什么?
这个就需要从继承的含义来说起了。
对于public继承,基类的public成员在派生类中依然是public的,故对用户是可见的,通过一个派生类的实例是仍然访问到这些base的public成员。而用户通过一个base类实例也只能访问到publc部分,故将一个派生类转换成为一个base类是合理的,它没有改变派生类中的base类成员对外的可见性。
对于protected或private继承,base类中的public部分在派生类中为protected或是private,那么通过一个派生类的实例是无法访问到派生类中的base类的public成员。如果将这种派生类能合法地转换成base类,则可以通过base类实例来访问派生类中base类的public成员了。这明显是破坏了派生类中的base类的public成员对外的可见性了,当然不合法了。要不然的话,通过一个private或protected的派生类实例无法访问到base类的public成员,我只需要通过转换成base类就可以访问了呢。这样的话,不同类型的派生类中对基类成员的可见性的设置就毫无意义了。
结案陈词:
c++的赋值兼容规则和类类型转换只适用于public方式的派生类和它对应的base类。