可以在运行时确定 virtual 函数的调用
将基类类型的引用或指针绑定到派生类对象对基类对象没有影响,对象本身不会改变,仍为派生类对象。对象的实际类型可能不同于该对象引用或指针的静态类型,这是 C++ 中动态绑定的关键。
在编译时确定非 virtual 调用
非虚函数总是在编译时根据调用该函数的对象、引用或指针的类型而确定。
覆盖虚函数机制
使用作用域操作符。
为什么会希望覆盖虚函数机制?最常见的理由是为了派生类虚函数调用基类中的版本。 在这种情况下, 基类版本可以完成继承层次中所有类型的公共任务,而每个派生类型只添加自己的特殊工作。
虚函数与默认实参
在同一虚函数的基类版本和派生类版本中使用不同的默认实参几乎一定会引起麻烦。如果通过基类的引用或指针调用虚函数,但实际执行的是派生类中定义的版本,这时就可能会出现问题。在这种情况下,为虚函数的基类版本定义的默认实参将传给派生类定义的版本,而派生类版本是用不同的默认实参定义的。
此外在这里提一下实现多态的方法有哪些。
除了c++的这种多态的实现机制之外,还有另外一种实现机制,也是查表,不过是按名称查表,是smalltalk等语言的实现机制。这两种方法的优缺点如下:
1、按照绝对位置查表,这种方法由于编译阶段已经做好了索引和表项,所以运行速度比较快;缺点是:如果这个派生体系比较大的时候,就浪费了很多的空间。
比如:GUI库,以MFC库为例,MFC有很多类,都是一个继承体系;而且很多时候每个类只是1,2个成员函数需要在派生类重写,如果用C++的虚函数机制,每个类有一个虚表,每个表里面有大量的重复,就会造成空间利用率不高。于是MFC的消息映射机制不用虚函数,而用第二种方法来实现多态,那就是:
2、按照函数名称查表,这种方案可以避免如上的问题;但是由于要比较名称,有时候要遍历所有的继承结构,时间效率性能不是很高。