今天看到师兄写的证书库代码,看到了一个很奇怪的东东,父类里有一个不是虚函数的函数,这个函数在子类中被重新写了一遍,函数名,参数列表,返回值都一样,就是在参数列表中的默认值给的不太一样。我觉得太诡异了。加上以前c++的重写和重载之类的概念也好长时间没弄,糊涂了。真不知道这个四不像是什么了。在网上翻了一些文档,发现这篇写的非常完整,而且和我想的也一样。其实师兄的这种写法是非常ugly的。如果出现这种子类中完全重新写了父类的函数,那么父类就应该将这个函数设为virtul的才对。当然如果没有设置,编译也不会出错,这种情况下,会出现hide隐藏。隐藏(hide):指的是派生类的成员函数隐藏了基类函数的成员函数.隐藏一词可以这么理解:在调用一个类的成员函数的时候,编译器会沿着类的继承链逐级的向上查找函数的定义,如果找到了那么就停止查找了,所以如果一个派生类和一个基类都有同一个同名(暂且不论参数是否相同)的函数,而编译器最终选择了在派生类中的函数,那么我们就说这个派生类的成员函数"隐藏"了基类的成员函数,也就是说它阻止了编译器继续向上查找函数的定义。而overload重载与继承根本就没关系,说的是同一个作用域中,相同类名,不同参数列表的现象。
转载的原文见下面:
C++是一门magic的语言,很多机制复杂得让人头疼,但是这种迷宫竞走的状态让人精力十足,我发誓了,不搞明白不罢休,同时也希望得到高手们的指点和帮助~
override 函数名和参数类型以及返回类型必须相同,即签名都是一致的——或者叫相貌和衣服都是一样的,一般用在继承过程中。(高手判断一下,除了实现细节,其他的是不是什么都应该相同?所以叫做“重写”——《C++编程思想》上是这么翻译的。)
overload 函数名必须相同,签名必须不同(参数个数,顺序,类型),返回类型可以不同,用在同一个类中,在编译时候确定。
以下是转载的内容:
override 是指在不同作用域中,多个函数原型完全一样,而实现却不同的函数。在C++中,经常发生在类的继承中。当基类中的某个方法是virtual或pure virtual函数时
(当然访问权限必须是public或protected,因为从C++设计思想上来讲private的函数不会是virtual的!!!这个请问一下,是不是这样的??),
其子类中对该方法的重新实现就属于override(重写)。
使用时,可以通过基类的指针或者引用所指向的具体对象来确定调用的是哪个方法,从而实现函数的多态。
(函数的多态?C++中实现多态性的手段之一吗?还有多少其他的手段??)
对于基类中的非virtual类型的成员函数,若其子类中也声明了与该函数名称相同的函数,那么基类中的该函数(也许是一系列函数,如果该函数在基类中有重载的话)将被隐藏,可以通过域解析操作符来调用。不过按照C++的设计思想来说呢,基类中的非virtual类型的成员函数,是不需要在子类中进行修改的,所以如果在子类中出现了这种隐藏的情况,说明应该将基类中的该函数改成virtual类型的,然后就是override了!
overload则是指在相同作用域中,多个函数具有相同的名字,但参数的数目和类型各不相同(当然相同数目和类型,如果顺序不同也是可以的),因为函数重载的机制是在C++中函数的签名与其参数有关,而不像C中,只与函数名有关。
总之,override与overload的一个最大的区别就是作用域不同,以及函数原型是否相同.
override: 覆盖是子类重写父类的虚方法的一种形式。
overload: 重载是值允许存在重名的多个方法。而这些函数的参数列表不同(或者是参数
的个数不同、或者是参数的类型不同或者两者都不同)。
重载(overload 与多态的概念无关) :因为是在编译阶段就确定的。
只有在与运行阶段确定的才称为面向对象的多态性。即override
面向对象的几个基本概念
多态:目的实现接口重用
继承:实现代码重用。
封装:实现代码的模块化.
override 表示重写,用于继承类对基类中虚成员的实现
overload 表示重载,用于同一个类中同名方法不同参数(包括类型不同或个数不同)的实现