2012-03-18 118 views

回答

6

当你有声明为virtual一个基类方法,为了覆盖它,你需要提供一个功能,在派生类(共变的返回类型被允许虽然)完全相同的签名。

如果你的函数名是相同的,但在派生类中签名从一个基类变化比它不是overidding了,这是function Hiding,派生类的方法隐藏基类的方法。

函数重载永远不会跨类,您可以重载同一类或自由函数中的方法,但不能跨类。当你试图通过类来完成时,你最终得到的是函数隐藏。

要将基类方法引入到派生类的范围中,您需要向Derived类添加
其他using functionName

编辑:
至于何时在重载使用virtual的Q,答案是:
如果你想你的类的功能,将其覆盖以运行时多态性,你应该将其标记为virtual,而不是如果你不打算的话。

读取良好:
When to mark a function in C++ as a virtual?

+0

要重载派生类中的基类成员函数,只需要一个'using'声明。 – Potatoswatter 2012-03-18 07:18:20

+0

@Patatoswatter:是的,除了提供方法之外,您还需要这样做,因此从这个意义上说,它不仅仅提供重载版本。 – 2012-03-18 07:19:22

+0

我也在试图制定一个答案,但我无法解释在基础虚拟中做出功能与否之间的差异。您可以在派生类中使用相同的方式重载两者(使用不同的签名)。我认为这是OP问题的一部分。 – 2012-03-18 07:22:44

3

重载是从(正交)虚拟首要完全分开的。

重写时,一个函数被替换为另一个相同的签名。然后有一些规则选择“最重要的”功能,这对于虚拟功能来说意味着在最派生的类中定义的功能。作为虚拟函数的特例,签名的返回类型可能略有不同(协方差)。

在重载中,具有不同参数类型的函数签名同时充当您进行函数调用时要选择的候选项。有一套非常复杂的规则来挑选合适的规则,这在95%的时间内运行良好,当它不合作时会让你头疼。

由于重载使用不同的签名和重写使用相同签名的作品,因此它们并不会真正互相干扰。

您可以显式地将基类的函数导入派生类,以扩展重载的函数名称。这由派生类中的using base_class::overload_name;完成。

0

我相信你的意思是覆盖非虚函数,而不是重载。当您在派生类中重写非虚拟基类函数时,则在编译时解析并绑定对该函数的调用。这意味着函数调用是根据调用函数的类型(或指针)来解析的。如果您在基类指针上调用该函数,则始终调用基类版本。如果您使用派生类指针,则始终调用派生版本;不管它指向的实际对象如何。

如果基类版本被标记为虚拟的,那么调用解析或绑定被延迟为在运行时基于调用的对象的类型而不是基于正被用于指针的类型拨打电话。这意味着您可以使用基类指针指向基类和派生类对象,然后调用该函数。根据指针指向的对象类型,调用相应的函数版本。这意味着如果我的指针指向基类对象,那么将调用基类版本。如果指针指向派生类型对象,则调用派生的版本。

+0

要说一个派生类** overiddes **的基类功能,关键字'虚拟'必须涉及否则,它不overidding。 – 2012-03-18 07:57:31

+0

不,它仍然是压倒一切的。但是,如果您不使用虚拟,那么基类版本会被派生类版本所取代。而且没有办法选择你想要使用的版本。现在,如果您想让所有重写的版本仍然可用,那么您应该将它们标记为虚拟。 – Drona 2012-03-18 08:15:51

+0

对不起,打破它给你,但它不正确,如果没有'虚拟'关键字,那么它不overveding。 – 2012-03-18 08:19:22