重载与覆盖初学者比较容易搞混的两个知识点,它们都是在子类父类的同名方法之间的关系。其实这两者之间的区别并不难。
重载与覆盖
重载与覆盖的最大区别就是在于覆盖的函数必须保持参数列表完全相同,而重载的函数参数列表必须有所不同。也就是看参数。当然还有其他的区别:覆盖的函数在父类需要声明为虚函数,加上virtual标示符。从深层次来讲:重载的函数是编译器对于函数命名的一种使用,对于编译器中的函数名来讲,它会将函数的参数加到函数名上去,比如fun(int a)函数在编译器里的命名有可能变成了fun_int。所以重载函数依然是一种早绑定。而覆盖函数是为了实现多态,它的函数需要实现晚绑定。也就是在执行的时候才可以决定到底是用哪个函数来执行。使用了virtual这个关键字也就是说明需要晚绑定。在执行的时候函数会依照对象归属的类来调用函数。如果是子类的对象,则会调用子类的函数,如果是父类,则会调用父类的函数。下面是一个例子:
这个程序执行的结果为:
前六行结果没有太多问题,在使用指针调用函数的地方我们可以发现在调用foo函数是,虽然是base的指针,但是函数却调用了derived的函数,说明实行了动态绑定(晚绑定),而其他的两个函数都调用了base的。
虚继承
虚继承也是一个带有virtual的东西,所有带有virtual的东西都是为了实现动态绑定的。虚继承也是这样子的。虚继承是class derive: public virtual base。或者class derive:virtual public base,virtual和public的位置可以互换。虚继承的出现是为了弥补多重继承的缺陷。例如有 那么在D的眼中,B和C的父类是两个不同的类,也就是讲如果新建了一个D,那么会有两个A建出来,那么对于A中的方法,参数会出现重复定义的错误。为了解决这个问题,使用了虚继承,使用了虚继承后新建D的时候只有一个A会建出来,这样就不会出错了。