【问题标题】:What does the virtual keyword mean when overriding a method?覆盖方法时 virtual 关键字是什么意思?
【发布时间】:2011-06-18 16:31:10
【问题描述】:

virtual 关键字在重写方法时有什么作用?我没有使用它,一切正常。

每个编译器在这方面的行为是否相同?

我应该使用它还是不使用它?

【问题讨论】:

  • @Harald:不。不同的主题。
  • 但我问的是该关键字的用法。与抽象虚拟方法无关。
  • 派生类中的虚拟关键字是可选的,但最好跳过它。否则,如果您有很多派生类,并且想要将继承的方法之一设为虚拟,则必须在所有这些派生类中为该方法添加 virtual 关键字。

标签: c++ virtual-functions


【解决方案1】:

没有它,您无法覆盖成员函数。

你只能隐藏一个。

struct Base {
   void foo() {}
};

struct Derived : Base {
   void foo() {}
};

Derived::foo覆盖Base::foo;它只是隐藏它,因为它具有相同的名称,如下所示:

Derived d;
d.foo();

调用Derived::foo

virtual 启用多态性,以便您实际上覆盖函数:

struct Base {
   virtual void foo() {}
};

struct Derived : Base {
   virtual void foo() {} // * second `virtual` is optional, but clearest
};

Derived d;
Base& b = d;
b.foo();

这会调用Derived::foo,因为它现在覆盖 Base::foo——你的对象是多态的。

(由于the slicing problem,您还必须为此使用引用或指针。)


  • Derived::foo 不需要重复 virtual 关键字,因为 Base::foo 已经使用了它。这是由标准保证的,您可以依赖它。不过,为了清楚起见,有些人认为最好保留这一点。

【讨论】:

  • 我知道在声明可以被覆盖的方法时 virtual 是必要的。我问过在覆盖方法时使用这个关键字,而不是声明。
  • @Miro:我不关注。您通过声明另一个覆盖它的函数来覆盖它。不管怎样,至少我的最后一段回答了你的问题。
【解决方案2】:

基类中的virtual 方法将通过层次结构级联,使每个具有相同签名的子类方法也virtual

class Base{
public:
  virtual void foo(){}
};

class Derived1 : public Base{
public:
  virtual void foo(){} // fine, but 'virtual' is no needed
};

class Derived2 : public Base{
public:
  void foo(){} // also fine, implicitly 'virtual'
};

如果仅用于文档目的,我建议您编写 virtual

【讨论】:

    【解决方案3】:

    当一个函数是虚拟的时,它在整个层次结构中都保持虚拟,无论您是否每次都明确指定它是虚拟的。覆盖方法时,使用 virtual 以更明确 - 没有其他区别:)

    class A
    {
        virtual void f() 
        {
          /*...*/
        };
    };
    
    class B:public A;
    {
        virtual void f()  //same as just void f()
        {
            /*...*/
        };
    };
    

    【讨论】:

      【解决方案4】:

      Extending on Light Races answer,也许这会帮助一些人看看它在做什么。

      struct Base {
      public:
          void foo() {
              printf_s("Base::foo\n");
          }
      };
      
      struct Derived : Base {
          void foo() {
              printf_s("Derived::foo\n");
          }
      };
      
      struct BaseVirtual {
      public:
          virtual void foo() {
              printf_s("BaseVirtual::foo\n");
          }
      };
      
      struct DerivedVirtual : BaseVirtual {
          virtual void foo() {
              printf_s("DerivedVirtual::foo\n");
          } 
      };
      
      Derived d;
      d.foo(); // Outputs: Derived::foo
      
      Base& b = d;
      b.foo(); // Outputs: Base::foo
      
      DerivedVirtual d2;
      d2.foo(); // Outputs: DerivedVirtual::foo
      
      BaseVirtual& b2 = d2;
      b2.foo(); // Outputs: DerivedVirtual::foo
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-14
        • 2010-10-29
        • 2011-10-28
        • 1970-01-01
        相关资源
        最近更新 更多