【问题标题】:Is C++ virtual definition inherited automatically?C++ 虚拟定义是自动继承的吗?
【发布时间】:2015-05-08 14:54:48
【问题描述】:

C++ 虚拟定义是递归的吗?考虑

class Foo
     {
     public:
          virtual void a()=0;
     };

class Bar:public Foo
     {
     public:
         void a()
             {
         //...
             }
     };

如果我现在继承Bar并再次重载a,那a也是多态的吗?

递归意味着

给定一个类A,它有一个虚拟成员a,以及n的一个虚拟成员:A的子类,那么a也是n+1的一个虚拟成员: th 子类,适用于所有 n

也就是说,虚函数遵循Peanos归纳公理,并且在一级之后不会终止。

【问题讨论】:

  • 我想,你已经展示了重新定义的例子,它没有重载
  • 不是“重载”,而是“覆盖”。
  • 是的,...覆盖。在任何情况下都需要virtual 关键字
  • 加一个,比如“Peanos 归纳公理”。这对星期五来说很豪华。

标签: c++ polymorphism virtual


【解决方案1】:

如果你继承自 Bar 你应该有

class Bar:public Foo
     {
     public:
         virtual void a() override
             {
         //...
             }
     };

所以你在这里说的是关于a() 的两件事:

  1. 该函数是虚拟的,因此从Bar 派生的任何内容都会将该函数视为虚拟
  2. 您正在从基类Foo 重写函数a

正如@MikeSeymour@Bathsheba 所提到的,Bar 中的virtual 关键字是多余的,因为该函数将被视为virtual,因为它位于基类中。但是,我倾向于使用virtual/override 的习惯,如我的示例所示,因此可以立即清楚如何在类的第一眼中使用此函数,而不必走上继承。

【讨论】:

  • +1,尽管我认为您应该提到 override 关键字是 C++11 特定的,仅用于生成错误消息(不是强制性语法)。
【解决方案2】:

“递归”不是正确的词;但是是的,覆盖虚函数的函数本身就是虚函数。

【讨论】:

    【解决方案3】:

    在基类和子类中具有 (i) 相同名称、(ii) 相同参数类型和 (iii) 相关 返回类型且在基类中标记为 virtual 的任何函数类在子类中也将是虚拟的。

    所以是的,void bar::a() 也是虚拟的。其实子类函数中的virtual-ness是没有办法去掉的。

    您的条款不准确。 重载 与具有相同名称但不同参数类型的函数有关。 递归是一种控制流技术。 重写是在子类中重新实现基类函数。

    【讨论】:

    • 是的,递归是一种控制流技术。但也有术语递归定义。这是根据根案例定义对象的定义。您可以说目录等的递归文件权限......
    【解决方案4】:

    在正常情况下,被覆盖的虚函数本身就是虚函数。父类函数是虚拟的,是因为您使用了virtual 关键字,还是因为它自己的父类是虚拟的,这并不重要。

    要注意的一件事是,当您“隐藏”一个功能与另一个同名但签名不同的功能时。该函数不是虚拟的!

    class Foo
         {
         public:
              virtual void a()=0;
         };
    
    class Bar:public Foo
         {
         public:
             void a(); // virtual
         };
    
    class Baz1 : public Bar
         {
         public:
             void a(); // also virtual
         };
    
    class Baz2 : public Bar
         {
         public:
             void a(int); // not virtual!
         };
    

    【讨论】:

      猜你喜欢
      • 2016-03-26
      • 2011-01-08
      • 1970-01-01
      • 2017-03-31
      • 1970-01-01
      • 2015-09-09
      相关资源
      最近更新 更多