虽然用qt在做项目,也用过重载和重写,但是某些时候还是要好好顺一下思路的。网上看过很多文章,有的讲的很深,甚至到分析汇编和内存的地步。但我觉得对于使用者来说,更需要用简单的方式验证一下,或者说从使用的角度看懂什么意思即可。
首先我的个人意见是,要明确一些概念。所谓多态或许是指面向对象的编译器实现角度去解释。而对于使用者,为了好理解,完全可以有单独的一套理论,这不会造成混淆。这里不讨论重载,只讨论重写。
对于一个派生类的实例对象,声明的类型可以是自己和所有长辈。类型不同,其函数的行为就不同。换句话说,派生类的对象,可以执行长辈类的行为。我觉得这就叫使用角度的多态。
所以我的结论刚好和网上普遍的说法不同,有虚函数不会造成使用角度的重写多态,没有虚函数才会有使用角度的重写多态。
直接上代码:
#include#include class Parent { public: virtual void f_virtual() { qDebug() << "base" << __FUNCTION__; } void f() { qDebug() << "base" << __FUNCTION__; } void f_self() { qDebug() << "base" << __FUNCTION__;} }; class Child : public Parent { public: void f_virtual() { qDebug() << "child" << __FUNCTION__; } void f() { qDebug() << "child" << __FUNCTION__; } }; int main(int argc, char *argv[]) { Parent *c1 = new Child; c1->f_virtual(); c1->f(); c1->f_self(); Child *c2 = new Child; c2->f_virtual(); c2->f(); c2->f_self(); }
main函数有效代码8行,一个子类,分别用父类和子类的类型来声明它,而后调用其函数。
而这些函数无非就三种:虚函数重写,非虚函数重写,继承函数。
这里不用猜,直接看结果:
Debugging starts child f_virtual base f base f_self child f_virtual child f base f_self Debugging has finished
对于虚函数:我认为之所以叫它“虚”,就是废了,无论怎样都是调用子类重写的函数。
对于非虚函数:我认为这才叫使用角度的多态,根据声明类型的不同,调用了父类或者子类的函数。
对于继承函数:父类直接遗传,只能按照父类的执行。
当然,上面的描述不严谨,也不一定准确,这里不是要纠结概念和理论,仅仅在使用角度考虑,用不用virtual,是否重写,会有什么效果,仅此而已。



