重写方法时 virtual 关键字意味着什么?

发布于 2024-11-15 20:24:43 字数 107 浏览 2 评论 0原文

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

每个编译器在这方面的行为都相同吗?

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

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 regard?

Should I use it or not?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

诗化ㄋ丶相逢 2024-11-22 20:24:43

如果没有它,您就无法重写成员函数。

您只能隐藏一个。

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,因为现在 >overrides Base::foo — 你的对象是多态的。

(由于切片问题<,您还必须为此使用引用或指针/a>.)


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

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.
风轻花落早 2024-11-22 20:24:43

基类中的虚拟方法将在层次结构中级联,使具有相同签名的每个子类方法也成为虚拟方法。

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

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.

最美的太阳 2024-11-22 20:24:43

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

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

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

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()
    {
        /*...*/
    };
};
平定天下 2024-11-22 20:24:43

扩展 Light Races 的答案,也许这会帮助一些人了解它在做什么。

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文