重写方法时虚拟关键字的含义是什么?

kra*_*mir 12 c++ virtual-functions

重写方法时关键字virtual会做什么?我没有使用它,一切正常.

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

我应该使用它吗?

Lig*_*ica 10

没有它,你不能覆盖成员函数.

你只能隐藏一个.

struct Base {
   void foo() {}
};

struct Derived : Base {
   void foo() {}
};
Run Code Online (Sandbox Code Playgroud)

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

Derived d;
d.foo();
Run Code Online (Sandbox Code Playgroud)

调用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();
Run Code Online (Sandbox Code Playgroud)

这会调用Derived::foo,因为现在会覆盖 Base::foo - 您的对象是多态的.

(由于切片问题,您还必须使用引用或指针.)


  • Derived::foo不需要重复virtual关键字,因为Base::foo已经使用过它.这是标准的保证,你可以信赖它.但是,有些人认为最好保持清晰.

  • 我知道在声明可以覆盖的方法时虚拟是必要的.我曾经问过在重写方法时使用这个关键字,而不是声明. (2认同)

Xeo*_*Xeo 8

一个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'
};
Run Code Online (Sandbox Code Playgroud)

virtual如果仅用于文档目的,我建议写一下.


Arm*_*yan 6

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

class A
{
    virtual void f() 
    {
      /*...*/
    };
};

class B:public A;
{
    virtual void f()  //same as just void f()
    {
        /*...*/
    };
};
Run Code Online (Sandbox Code Playgroud)