开发者

What does the virtual keyword mean when overriding a method?

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

Does every compiler behave the sam开发者_运维知识库e in this regard?

Should I use it or not?


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.


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.


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()
    {
        /*...*/
    };
};


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜