12. 虚函数与多态
Inheritance(继承) with virtual functions(虚函数)
- non-virtual函数(不是虚函数):你希望drived class(子类)不要重新定义(overide,覆盖)。
- virtual(虚)函数:你希望devired class(子类)最好去重新定义(overide),且你对它(指父类的虚函数)已有默认定义。
- pure virtual(纯虚)函数:你希望devired class(子类)一定重新定义(overide),你对它(指父类的虚函数)完全没有默认的定义(其实可以由定义,但你不去定义它)。
- 写笔记的时候可以考虑多用点副词,以加深印象。
注解:
- 任何一个成员函数前面加上一个virtual进行修饰,它就会成为虚函数。
- 在继承的关系里面,所有的东西都可以被继承下来,这包括私有数据和函数的调用权限。函数的继承继承的是调用权。
- 子类可以调用父类的所有成员函数,但子类在调用的时候要不要重新定义呢?见行文一开始的1、2 、3.
注解:
- 父类有时候只设计了一个框架,有些动作父类不知情,所以完成不了,这时候就需要设计成虚函数,在子类中实现。
- 在main()函数中,首先创建一个子类的对象,通过子类对象调用父类函数(在面向对象的编程中,这是一个非常经典的想法)。
- 最关键的那一刻是:Serialize()的实现在子类中,调用路线是遇到父类中的Serialize()就跑去子类中找具体的实现。
- 父类中的Serialize()函数也许3年前就设计好了,但是一直没实现,等着客户去实现,这就是设计模式、模板模式(Templat Method)。
- myDoc调用父类的OnFileOpen(),myDoc(谁调用我的那个谁)就会成为隐藏的this pointer.从编译器的角度考虑,它会这样写CDocument::OnFileOpen(&myDoc);&myDoc,即myDoc的地址是隐藏的参数,它将被传到父类中的OnFileOpen()函数的参数中。
- this->Seirialize(); 值通过this 调用Seirialize(),this是谁?this是&myDoc。
- Inheritance+Composition关系下的构造和析构函数的调用顺序(?)
注解:
注解:
- Base,Component, Derived可以认为是类名。
- 构造函数的调用顺序是:由内而外。
- 析构函数的调用顺序是:跟构造函数调用顺序相反。