C ++中虚函数的行为

时间:2010-04-19 17:58:56

标签: c++ virtual-functions

我有一个问题,下面是两个类:

  class Base{
      public:
          virtual void toString();       // generic implementation
  }

  class Derive : public Base{
      public:
          ( virtual ) void toString();   // specific implementation
  }

问题是:

  • 如果我想使用 Base 类型的指针来创建类 Derive 的子类,是否需要括号中的关键字virtual?

  • 如果答案为否,那么有和没有虚拟的派生的成员函数 toString 有什么区别?

7 个答案:

答案 0 :(得分:13)

C ++03§10.3/ 2:

  

如果虚拟成员函数vf是   在类Base和a中声明   class派生,直接派生或   成员之间的间接来自Base   函数vf具有相同的名称和   与Base :: vf相同的参数列表是   声明,然后 Derived :: vf也是   虚拟的(无论是否如此   声明)并覆盖   基:: VF。

答案 1 :(得分:10)

那个关键字是严格可选的,完全没有区别。

答案 2 :(得分:7)

virtual属性继承自基类,即使您没有输入它,也会被认为存在。

答案 3 :(得分:1)

编译器已经从基类中的'virtual'关键字知道toString是一个虚方法。无需重复。

答案 4 :(得分:1)

虚拟永远是虚拟 的功能。

因此,在任何情况下,如果虚拟关键字未在后续类中使用,则不会阻止函数/方法“虚拟”,即被覆盖。因此,以下指南可能有助于团队发展的观点: -

  • 如果应该使用函数/方法 被覆盖,总是使用 'virtual'关键字。这是特别的 在interface / base中使用时为true 类。
  • 如果应该派生类 进一步明确分类 陈述每个人的'虚拟'关键字 可以的功能/方法 重写的。
  • 如果派生的函数/方法 上课不应该是 再次分类,然后关键字 '虚拟'将被评论 表示功能/方法 被覆盖但没有 进一步覆盖它的类 再次。这个当然不能阻止 有人来自压倒一切 派生类除非上课 是最终的(不可导出的),但它 表示该方法不应该是 覆盖。 例如:/*virtual*/ void someFunc();

答案 5 :(得分:0)

编译器与您在函数的派生版本上提供虚拟关键字无关。

但是,无论如何都要提供它,这样任何查看代码的人都可以告诉它是一个虚函数。

答案 6 :(得分:0)

这是一个好的风格问题,用户程序员知道发生了什么。在C ++ 0x中,您可以使用[[override]]使其更明确和可见。您可以使用[[base_check]]强制使用[[override]]。

如果您不想或不想这样做,只需使用虚拟关键字。

如果你在没有虚拟toString的情况下派生,并且你将Derive的实例强制转换回Base,那么调用toString()实际上会调用Base的toString(),因为只要它知道它是Base的实例。