先定义基类与派生类
//基类
class A{
public:
int a1;
virtual int f() const;
};
//派生类
class B : public A{
public:
int b1;
int f() const override;
};
在使用基类的引用(或指针)时,实际上我们并不清楚该引用(或指针)所绑定对象的真实类型,该对象可能是基类对象,也可能是派生类对象。因此有了如下类型区分:
静态类型与动态类型
- 静态类型在编译时总是已知的,它是变量声明时或表达式生成的类型
- 动态类型则是变量或表达式表示的内存中的对象的类型,动态类型直到运行时才可知
- 只有基类的指针或引用的静态类型可能与其动态类型不一致,如:
//pt的静态类型与动态类型都为A A* pt = new A(); //pt的静态类型为A,动态类型为B A* pt = new B();
访问特性
- 只有当B公有的继承A时,用户代码才能使用派生类向基类的转换;如果B继承A的方式是受保护的或者私有的,则用户代码不能使用该转换
- 不论B以什么方式继承A,B的成员函数和友元都能使用派生类到基类的转换
- 如果B继承A的方式是公有的或者受保护的,则B的派生类的成员函数和友元可以使用B向A的类型转换;如果是私有继承,则不能使用。