#include<iostream> using namespace std; class A { public: void asd() { pri(); } private: /*virtual*/ void pri() { cout << "基类函数" << endl; } }; class B :public A { private: void pri() /*override*/ { cout << "派生类函数" << endl; } }; int main(void) { B k; A *a = &k; a -> asd(); return 0; }
这段代码是是以前virtual以前没认识到的地方,间接用指针或者引用调用虚函数还是动态绑定。
对动态绑定认识不够深刻啊,
指针|引用&virtual。
条款35:考虑virtual函数的其他选择
例子,游戏角色健康指数
温习:
1、使用no virtual interface(NVI)手法,那是template method设计模式的一种特殊形式,他以公有非虚函数包裹较低访问级(保护和私有)的函数。
2、将virtual函数替换为函数指针成员变量,这是strategy设计模式的一种分解表现形式。
3、以function<>成员变量替换virtual函数,因而允许使用任何可调用物搭配一个兼容于需求的签名式,这是strategy设计模式的一种形式。
4、将继承体系的virtual函数替换为另一个继承体系的virtual函数,这是strategy设计模式的传统实现手法。
请记住
1、virtual函数的替代方案包括NVI手法以及strategy设计模式的多种形式。NVI手法自身是一个特殊形式的template method设计模式。
2、将技能从成员函数移动到class外部函数接口,带来的一个缺点是,非成员函数无法访问class的非公有成员。
3、function<>的行为就像一般函数指针。这样的对象可接纳“与给定之目标签名式”相同的所有可调用物。
条款36:绝对不重新定义继承而来的novirtual函数
1、公有继承的派生类是基类的一种,对基类能够适应所有派生类的是novirtual函数(派生类和基类执行方式完全相同),基类不该修改,否则应该设置为virtual函数(派生类和基类执行方式不同)。
2、比如条款7的徐析构函数事实就是该条款的一部分。
条款37:绝对不重新定义继承而来的缺省参数值
1、绝对不要重新定义一个继承而来的缺省参数值,因为缺省参数值都是静态绑定,而virtual函数,你唯一应该覆写的东西--却是动态绑定。