在绝大多数情况下,静态类型与动态类型都是必须一致的,如果不一致,将发生隐式类型转换或引发编译错误 。当且仅当使用基类的指针或引用存储继承类对象时,变量的静态类型与动态类型将不一致 。
此时,虽然看上去发生了向上类型转换,但实际上并未发生,此过程称为动态绑定 。
一个变量的静态类型,决定了由此变量能够访问到的成员名称 。当静态类型是基类指针或引用时,即使变量存放的是继承类对象,也只能够访问到基类中声明的成员名称 。
即:如果发生向上类型转换的类型是类的指针或引用,则将以丢失继承类部分的成员名称为代价进行向上类型转换 。
但由于虚函数的存在,访问成员名称所得到的实际成员函数将不一定与静态类型保持一致,此性质是 C++ 多态的核心 。虚函数相关话题与本文无关,这里不再详述 。
5.2 阻止向上类型转换
让我们重新思考这样一个问题:为什么继承类可以访问基类的成员?
不难发现,“继承类可以访问基类成员”这一性质并不是天经地义的,因为继承类中并没有“复制粘贴”一个基类,而只有继承类本身的部分,故原则上继承类虽然继承了基类,但其本身仍然是没有能力访问基类的成员的 。
继承类对象之所以能够访问基类成员,是因为在进行这样的访问时,继承类的 this 指针通过向上类型转换操作转换成了一个基类类型的指针,然后以基类指针的身份访问到了基类的成员 。
如果希望阻止这种隐式的向上类型转换呢?
让我们认真考察 public、protected 与 private 这三个关键字 。
按照常规的解读,这三个关键词用于限定类的用户的访问权,需要注意的是:“类的用户”不仅指类实例,也指继承此类的类 。
说明如下:
- public:当用于访问说明符时,表示对类的一切用户可见;用于继承时,表示继承时不修改基类的一切访问说明符
- protected:当用于访问说明符时,表示仅对类的继承用户可见,对类的实例用户不可见;用于继承时,表示将基类的一切 public 访问说明符在继承类中修改为 protected
- private:当用于访问说明符时,表示对一切类的用户均不可见;用于继承时,表示将基类的一切 public 和 protected 访问说明符在继承类中修改为 private
如果我们从向上类型转换这一角度思考,就能得出答案:
- public:不阻止任何用户进行向上类型转换
- protected:阻止类的实例用户进行向上类型转换
- private:阻止一切用户进行向上类型转换
参考以下代码:
struct A {};
struct B: A {}; // 不阻止任何B类的用户向A进行类型转换
struct C: protected A {}; // 阻止C类的实例用户向A进行类型转换
struct D: private A {}; // 阻止D类的一切用户向A进行类型转换
struct E: B { void test { static_cast<A *>(this); } }; // B类的继承类用户可以向A进行类型转换
struct F: C { void test { static_cast<A *>(this); } }; // C类的继承类用户可以向A进行类型转换
struct E: D { void test { static_cast<A *>(this); } }; // Error!D类的继承类用户不可以向A进行类型转换
int main
{
static_cast<A *>(new B); // B类的实例用户可以向A进行类型转换
static_cast<A *>(new C); // Error!C类的实例用户不可以向A进行类型转换
static_cast<A *>(new D); // Error!D类的实例用户不可以向A进行类型转换
}
上述代码中,类 B、C、D 分别以三种不同的访问说明符继承自类 A,同时,我们分别为类B、C、D 各定义了一个继承类用户和一个实例用户 。
由此可见,public 继承将不阻止类的任何用户进行向上类型转换,而 private 继承将阻止类的一切用户进行向上类型转换,protected 继承只阻止类的实例用户进行向上类型转换,但不阻止类的继承类用户进行向上类型转换 。
5.3 多重继承与向上类型转换
对于多重继承,其向上类型转换对于同一继承层的多个基类是全面进行的 。
推荐阅读
- 梦见猴子缠着我甩不掉最后死了 梦见猴子缠着我甩不掉如何甩掉
- 局域网MAC地址认证上网如何实现
- C和C++标准库,这是什么玩意?
- 喝茶前如何洗茶 避免误操作的三大要领
- VLAN工作原理之ACCESS:接收到带VLAN的报文如何处理
- 如何选购与冲泡陈年普洱茶
- 胡萝卜炖排骨汤如何做才好吃?
- 红茶有哪些类别红茶类别如何区分
- 170男生如何穿搭,穿搭显高秘籍都在这里了,快来学习吧
- 阿里巴巴网店怎么开啊流程是怎样 如何阿里巴巴开店步骤