What does the virtual keyword mean when overriding a method?

前端 未结 4 882
生来不讨喜
生来不讨喜 2021-01-11 12:16

What does the keyword virtual do when overriding a method? I\'m not using it and everything works fine.

Does every compiler behave the same in this

相关标签:
4条回答
  • 2021-01-11 13:02

    A virtual method in the base class will cascade through the hierarchy, making every subclass method with the same signature also 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'
    };
    

    I'd recommend writing the virtual though, if for documentation purpose only.

    0 讨论(0)
  • 2021-01-11 13:03

    When a function is virtual, it remains virtual throughout the hierarchy, whether or not you explicitly specify each time that it is virtual. When overriding a method, use virtual in order to be more explicit - no other difference :)

    class A
    {
        virtual void f() 
        {
          /*...*/
        };
    };
    
    class B:public A;
    {
        virtual void f()  //same as just void f()
        {
            /*...*/
        };
    };
    
    0 讨论(0)
  • 2021-01-11 13:06

    You cannot override a member function without it.

    You can only hide one.

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

    Derived::foo does not override Base::foo; it simply hides it because it has the same name, such that the following:

    Derived d;
    d.foo();
    

    invokes Derived::foo.

    virtual enables polymorphism such that you actually override functions:

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

    This invokes Derived::foo, because this now overrides Base::foo — your object is polymorphic.

    (You also have to use references or pointers for this, due to the slicing problem.)


    • Derived::foo doesn't need to repeat the virtual keyword because Base::foo has already used it. This is guaranteed by the standard, and you can rely on it. However, some think it best to keep that in for clarity.
    0 讨论(0)
  • 2021-01-11 13:07

    Extending on Light Races answer, maybe this will help some people to see what it is doing.

    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
    
    
    0 讨论(0)
提交回复
热议问题