您的位置:首页 > 其它

重载与覆盖的区别4

2008-02-29 20:29 204 查看
[align=left]小结:[/align]
[align=left] [/align]
[align=left] 重载overload是根据函数的参数列表来选择要调用的函数版本,而覆盖是根据运行时对象的实际类型来选择要调用的虚virtual函数版本,覆盖的实现是通过派生类对基类的虚virtual函数进行覆盖override来实现的,若派生类没有对基类的虚virtual函数进行覆盖override的话,则派生类会自动继承基类的虚virtual函数版本,此时无论基类指针指向的对象是基类型还是派生类型,都会调用基类版本的虚virtual函数;如果派生类对基类的虚virtual函数进行覆盖override的话,则会在运行时根据对象的实际类型来选择要调用的虚virtual函数版本,例如基类指针指向的对象类型为派生类型,则会调用派生类的虚virtual函数版本,从而实现多态。[/align]
[align=left] [/align]
[align=left] 使用多态的本意是要我们在基类中声明函数为virtual,并且是要在派生类中覆盖override基类的虚virtual函数版本,注意,此时的函数原型与基类保持一致,即同名同参数类型;如果你在派生类中新添加函数版本,你不能通过基类指针动态调用派生类的新的函数版本,这个新的函数版本只作为派生类的一个重载版本。还是同一句话,重载只有在当前类中有效,不管你是在基类重载的,还是在派生类中重载的,两者互不牵连。如果明白这一点的话,在例6、例9中,我们也会对其的输出结果顺利地理解。[/align]
[align=left] [/align]
[align=left] 重载是静态联编的,覆盖是动态联编的。进一步解释,重载与指针实际指向的对象类型无关,覆盖与指针实际指向的对象类型相关。若基类的指针调用派生类的重载版本,C++编绎认为是非法的,C++编绎器只认为基类指针只能调用基类的重载版本,重载只在当前类的名字空间作用域内有效,继承会失去重载的特性,当然,若此时的基类指针调用的是一个虚virtual函数,那么它还会进行动态选择基类的虚virtual函数版本还是派生类的虚virtual函数版本来进行具体的操作,这是通过基类指针实际指向的对象类型来做决定的,所以说重载与指针实际指向的对象类型无关,多态与指针实际指向的对象类型相关。 [/align]
[align=left] [/align]
[align=left] 最后阐明一点,虚virtual函数同样可以进行重载,但是重载只能是在当前自己名字空间作用域内有效(请再次参考例6)。[/align]
[align=left] [/align]
[align=left]重载overload的特征:[/align]
[align=left]①相同的范围(在同一个类中,名字空间作用域);[/align]
[align=left]②函数名相同参数不同;[/align]
[align=left]③virtual 关键字可有可无[/align]
[align=left]④根据函数的参数列表来选择要调用的函数版本[/align]
[align=left]⑤静态联编[/align]
[align=left] [/align]
[align=left]覆盖override是指派生类函数覆盖基类函数,覆盖的特征是:[/align]
[align=left]①不同的范围(分别位于派生类与基类);[/align]
[align=left]②函数名和参数都相同;[/align]
[align=left]③基类函数必须有virtual 关键字。(若没有virtual 关键字则称之为隐藏hide)[/align]
[align=left]④覆盖是根据运行时对象的实际类型来选择要调用的虚virtual函数版本[/align]
[align=left]⑤动态联编[/align]
override可以翻译为覆盖,从字面就可以知道,它是覆盖了一个方法并且对其重写,以求达到不同的作用。对我们来说最熟悉的覆盖就是对接口方法的实现,在接口中一般只是对方法进行了声明,而我们在实现时,就需要实现接口声明的所有方法。除了这个典型的用法以外,我们在继承中也可能会在子类覆盖父类中的方法。在覆盖要注意以下的几点:
1、覆盖的方法的标志必须要和被覆盖的方法的标志完全匹配,才能达到覆盖的效果;
2、覆盖的方法的返回值必须和被覆盖的方法的返回一致;
3、覆盖的方法所抛出的异常必须和被覆盖方法的所抛出的异常一致,或者是其子类;
4、被覆盖的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行覆盖。
overload对我们来说可能比较熟悉,可以翻译为重载,它是指我们可以定义一些名称相同的方法,通过定义不同的输入参数来区分这些方法,然后再调用时,VM就会根据不同的参数样式,来选择合适的方法执行。在使用重载要注意以下的几点:
1、在使用重载时只能通过不同的参数样式。例如,不同的参数类型,不同的参数个数,不同的参数顺序(当然,同一方法内的几个参数类型必须不一样,例如可以是fun(int, float),但是不能为fun(int, int));
2、不能通过访问权限、返回类型、抛出的异常进行重载;
3、方法的异常类型和数目不会对重载造成影响;
[align=left] 注:[/align]
[align=left]虚函数表:编译器处理虚函数的方法是:给每个对象添加一个隐藏成员.隐藏成员中保存了一个指向函数地址数组的指针.这组数组称为Vtbl[/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: