【问题标题】:Using 'virtual' in derived class在派生类中使用“虚拟”
【发布时间】:2011-01-15 13:41:39
【问题描述】:

我最近在派生类中看到了代码,其中程序员将virtual 放在重写的函数前面。这很常见吗?我觉得这很奇怪,有点让我措手不及。

编辑:我不是在问 virtual 做什么,我是在问为什么有人会将 virtual 放在已经在其基类中覆盖虚函数的派生类中。

前:

class B {
 public:
  virtual void foo();
  ....
};

class D : public B {
 public:
  virtual void foo(); // could have just put void foo();
  ...
};

【问题讨论】:

  • 我也经常这样做,只是为了记录我的代码。
  • 这是我认为 C# 更好的地方,强制派生类使用 override 关键字。
  • 这是一个完美的问题,它回答了我关于虚拟工作原理的许多疑问。谢谢@Person
  • 这些答案已经过时了:从 C++11 开始,有一个 override keyword 在未来的代码中,请使用这个关键字来标记覆盖虚函数的函数在基类中。

标签: c++ virtual


【解决方案1】:

virtual 是最高(最少派生)级别的可覆盖函数所必需的。它是可选的,但在较低(更衍生)的水平上是无害的。这对自我记录代码很有好处。

【讨论】:

  • 没错。编译器已经知道了,但是其他阅读你的代码的人可能不得不通过多个头文件来查找。
【解决方案2】:

我假设您知道 virtual 关键字的用途,但想知道为什么它突然出现在子类型中。如果我弄错了,我的回答可能没有多大意义,但任何 C++ 参考都可以。

将 virtual 放在派生类中是完全合法的。因此,如果您有对该类或其任何子类的引用或指针,则此函数的调用将根据运行时类型动态绑定。

虽然合法,但是在基类中具有非虚拟方法并在被覆盖的版本中具有虚拟方法并不是好的设计。

一个原因是你可以有一个派生类的实例,然后一个指向基类的指针和一个指向派生类的指针,并且两个指针都指向这个实例。对每个指针调用相同的函数将产生不同的结果,因为调用基类声明的指针将针对基类中的定义。

【讨论】:

    【解决方案3】:

    我看不出有什么奇怪的地方。在许多情况下(如果不是大多数情况下),程序员通过从基类复制粘贴来在派生类中创建覆盖函数的声明。花费额外的精力手动删除多余的virtual 说明符是没有意义的。此外,显式的virtual 可以更容易地查看哪些函数是虚拟的。

    【讨论】:

      【解决方案4】:

      这很常见。许多风格指南都推荐它,例如Google。 目的是为了增强代码的可读性。

      【讨论】:

      【解决方案5】:

      这将有助于未来的推导。如果有人想派生D类并拥有虚函数,那很容易理解

      【讨论】:

        【解决方案6】:

        另一种增强可读性的方法是使用如下内容:

        class B {
         public:
          virtual void foo();
          ....
        };
        
        class D : public B {
         public:
          /*override*/ void foo();
          ...
        };
        

        【讨论】:

        • 当你有一个完全一样的目的的保留字时,写评论是没有意义的。记录代码的最佳方式是通过代码本身。我推荐阅读 Robert C. Martin 的“The Clean Code”,“Uncle” Bob。
        • 答案是在语言中没有“覆盖”关键字的那一天发布的;)
        【解决方案7】:

        这些答案(以及这种做法)已经过时了。 从 C++11 开始,您应该使用 override keyword 明确指定一个虚函数覆盖另一个虚函数。如果你尝试 override 一些不是基类中的虚函数的东西,你的编译器会抛出一个错误!

        【讨论】:

          猜你喜欢
          • 2023-03-23
          • 1970-01-01
          • 2020-10-26
          • 2011-10-29
          • 2019-11-04
          • 2017-11-15
          • 2013-10-07
          • 1970-01-01
          相关资源
          最近更新 更多