类型转换与继承

可以将基类指针/引用绑定到派生类对象上。也就是可以把派生类对象当成基类对象使用(需要传基类对象的参数也可以传派生类对象)但不能将基类转换成派生类。

静态类型与动态类型

  • 静态类型:变量或表达式在编译时确定的类型,由声明决定。代码写下时,编译器就能知道其静态类型
  • 动态类型:变量或表达式在运行时所表示的对象的实际类型。只有当程序运行时,才知道变量指向的具体对象是什么

基类指针或引用可以指向派生类对象,此时,静态类型仍然是基类类型,动态类型则是运行时绑定的派生类类型。即该指针或引用只能访问基类的成员,其中非虚函数调用的是基类的版本,虚函数会动态绑定到派生类定义的版本。

如果是直接将派生类对象赋值给基类,仅保留基类部分,派生类的成员被丢弃。之后,该对象的动态类型就变成了基类。

虚函数特性

所有虚函数都必须有定义。

当某个虚函数通过指针或引用调用时,对虚函数的调用在运行时才被解析。

覆盖规则

如果要在派生类中覆盖继承来的虚函数,形参类型必须完全一致。

否则名字相同但参数列表不同的函数会成为独立的新函数,而不是覆盖原有的。

因为声明在内层作用域的函数并不会重载声明在外层作用域的函数,而是隐藏外层的。

特殊说明符

  • 可以在派生类中使用override标记,此时如果没有覆盖原有的虚函数,编译器会报错
  • 单独将函数指定为final,之后任何尝试覆盖该函数的操作都会报错

其他注意事项

  • 虚函数总是使用基类中定义的默认实参
  • 可以使用作用域运算符规避虚函数的动态绑定