函数的重写
子类可以重写从父类继承而来的函数(overwriting)

class Parent
{
public:
	void Test();
};
class Child : public Parent
{
	public:
		void Test();
}

父类指针指向子类对象
可以将父类指针指向一个子类的对象,这是完全允许的
例如
//左侧为Tree *,右侧为AppleTree *

Tree * p=new AppleTree();

从普通的逻辑来讲,苹果是一种树,因而可以把AppleTree *视为一种Tree *
从语法本质上讲,子类对象的前半部分就是父类,因而可以将子类对象的指针直接转化为父类。

父类指针指向子类

int main()
{
	Child ch;
	ch.a=0x1111111;
	ch.b=0x2222222;
	Parent * p=&ch;
	printf("Parent::a=%d\n",p->a);
	return 0;
}

所以,从直观感觉到内在机理都允许这么做

问题:考虑一下情况,

Parent * p=new Child();
p->Test();

那么,此时调用的Test()是父类的、还是 子类的?

  1. 指针p的类型是Parent *
  2. 指针p指向的对象时Child *
    调用者的初衷:因为p指向的是对象时子类对象,所以应该调用子类的Test().

虚拟继承:virtual
当一个成员函数需要子类重写,那么在父类应该将其声明为virtual
(有时将声明为virtual的函数为“虚函数”)
例如

class Parent
{
	public:
	virtual void Test();
};

virtual 本身表明该函数即被子类重写

加virtual关键字是必要的
考虑一下情况,

Parent *obj=new Child();//语法允许,合乎情理
obj->Test();

此时,如果Test()在父类中被声明为virtual,是调用的是子类的Test()
这解释了virtual的作用,根据对象的实际类型,调用相应类型的函数。

注意:

  1. 只需要在父类中将函数声明为virtual,子类自动地就是virtual
  2. 即将被重写的函数添加virtual,是一条遵守的编码习惯

1.介绍继承关系中,对函数重写后的结果
2.介绍virtual关键字的作用和必要性(父类指针指向子类对象)