C++ 中虚函数的行为

发布于 2024-08-29 14:23:08 字数 499 浏览 4 评论 0原文

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

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

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

问题是:

  • 如果我想使用 Base 类型的指针来 Derive 类的子类执行多态性,则 is 关键字括号里的virtual有必要吗?

  • 如果答案是否定的,Derive类的成员函数toString有和没有virtual有什么区别?

I have a question, here are two classes below:

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

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

The question is:

  • If I wanna subclass of class Derive perform polymophism using a pointer of type Base, is keyword virtual in the bracket necessary?

  • If the answer is no, what's the difference between member function toString of class Derive with and without virtual?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

灼疼热情 2024-09-05 14:23:08

C++03 §10.3/2:

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

C++03 §10.3/2:

If a virtual member function vf is
declared in a class Base and in a
class Derived, derived directly or
indirectly from Base, a member
function vf with the same name and
same parameter list as Base::vf is
declared, then Derived::vf is also
virtual (whether or not it is so
declared)
and it overrides
Base::vf.

梦回梦里 2024-09-05 14:23:08

该关键字是严格可选的,没有任何区别。

That keyword there is strictly optional and makes no difference at all.

对风讲故事 2024-09-05 14:23:08

virtual 属性是从基类继承的,即使您没有键入它,也假定它存在。

The virtual property is inherited from the base class and is assumed to be present even if you don't type it out.

趴在窗边数星星i 2024-09-05 14:23:08

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

The compiler already knows from the 'virtual' keyword in the base class that toString is a virtual method. No need to repeat it.

淡淡绿茶香 2024-09-05 14:23:08

函数一旦是虚拟的,就永远是虚拟的

因此,无论如何,如果在后续类中不使用 virtual 关键字,它不会阻止函数/方法成为“虚拟”,即被覆盖。因此,从团队开发的角度来看,以下指南可能会有所帮助:-

  • 如果函数/方法应该
    被覆盖,总是使用
    “虚拟”关键字。这尤其是
    用于接口/基础时为 true
    类。
  • 如果派生类应该
    进一步明确地细分
    为每个声明“虚拟”关键字
    函数/方法可以是
    被覆盖。
  • 如果派生中的函数/方法
    类不应该是
    再次子类化,然后是关键字
    “虚拟”需要注释
    表明该函数/方法
    被覆盖但没有
    覆盖它的其他类
    再次。这当然不妨碍
    有人超越
    派生类,除非该类
    是最终的(不可导出的),但它
    表明该方法不应该是
    被覆盖。
    例如: /*虚拟*/ void someFunc();

A function once a virtual always a virtual.

So in any event if the virtual keyword is not used in the subsequent classes, it does not prevent the function/method from being 'virtual' i.e. be overridden. So the following guideline might help from a team development point-of-view :-

  • If the function/method is supposed to
    be overridden, always use the
    'virtual' keyword. This is especially
    true when used in interface / base
    classes.
  • If the derived class is supposed to
    be sub-classed further explicity
    state the 'virtual' keyword for every
    function/method that can be
    overridden.
  • If the function/method in the derived
    class is not supposed to be
    sub-classed again, then the keyword
    'virtual' is to be commented
    indicating that the function/method
    was overridden but there are no
    further classes that override it
    again. This ofcourse does not prevent
    someone from overriding in the
    derived class unless the class
    is made final (non-derivable), but it
    indicates that the method is not supposed to be
    overridden.
    Ex: /*virtual*/ void someFunc();
恬淡成诗 2024-09-05 14:23:08

无论您是否在函数的派生版本上提供virtual关键字,对于编译器来说都无关紧要。

然而,无论如何提供它都是一个好主意,这样任何查看你的代码的人都能够知道它是一个虚函数。

It doesn't matter to the compiler whether or not you supply the virtual keyword on derived versions of the function.

However, it's a good idea to supply it anyway, so that anyone looking at your code will be able to tell it's a virtual function.

美煞众生 2024-09-05 14:23:08

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

如果您不想或不能这样做,只需使用 virtual 关键字即可。

如果您在没有虚拟 toString 的情况下进行派生,并且将 Derive 的实例强制转换回 Base,则调用 toString() 实际上会调用 Base 的 toString(),因为据它所知,这是 Base 的实例。

It's a matter of good style, and the user-programmer knows what's going on. In C++0x you can use [[override]] to make it more explicit and visible. You can use [[base_check]] to force the usage of [[override]].

If you don't want or can't do that, simply use the virtual keyword.

If you derive without virtual toString, and you cast an instance of Derive back to Base, calling toString() would actually call Base's toString(), since as far as it know's that's an instance of Base.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文