关于c++中的虚函数的问题

发布于 2024-11-06 03:07:55 字数 766 浏览 0 评论 0原文

我是C++初学者,这几天在研究虚函数。 有一些问题让我很困惑。

例如:

class A {
  public:
  virtual void f() {
      //do something; 
  }
}

class B: public A {
   public:
   virtual void f() {
//do something;
}
}
  1. class A包含一个虚函数f(),而class B继承它。在class B内部,函数f()也被声明为virtual,所以这是否意味着class B<中的f() /code> 重载 A 类 中的 f()?它是否允许继承B的类重载f()?或者B是否定义了一个与class A中的f()不同的新虚函数?

  2. 虚函数提供了一种重载方法的方式。如果 B 继承 A 并且没有将 f() 声明为 virtual,则类可以 继承B的C重载f()并实现多态性?

I am a beginner of C++, I am studying virtual functions these days.
There are some questions confuse me a lot.

for example:

class A {
  public:
  virtual void f() {
      //do something; 
  }
}

class B: public A {
   public:
   virtual void f() {
//do something;
}
}
  1. class A contains a virtual function f(), and class B inherits it. Inside class B, the function f() is also declared as virtual, so does this mean f() in class B overloads f() in class A? Does it allow classes which inherit B to overload f()? Or does B define a new virtual function which is different from f() in class A?

  2. Virtual functions provide a way of overloading methods. If B inherits A and does not declare the f() as virtual, then can a class C which inherits B overload the f() and achieve polymorphism?

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

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

发布评论

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

评论(4

戈亓 2024-11-13 03:07:55

在B类内部,函数f()也被声明为virtual,那么这是否意味着B类中的f()重载了A类中的f()

不,它不会重载。它覆盖。此外,关键字 virtual 在类 B 中是可选的。无论您是否编写虚拟函数,B::f() 都将始终是虚拟函数。

当您定义名称相同但参数不同的函数时,将使用术语“重载”。在您的例子中,函数 f 的签名在两个类中完全相同,这意味着它不是重载;派生类基本上覆盖f()的基类定义。

inside class B, the function f() also be declared as virtual, so does this mean f() in class B overload f() in class A

No, it doesn't overload. It overrides. Also the keyword virtual is optional in class B. B::f() will always be a virtual function, whether you write virtual or not.

The term overload is used when you define a function with same name but different parameter(s). In your case, the signature of the function f is exactly same in both classes, that means it isn't overloading; the derived class basically overrides the base class definition of f().

下壹個目標 2024-11-13 03:07:55

Virtual 关键字允许您覆盖函数而不是重载它们。

另外,virtual 属性是继承的,因此 virtual 关键字对于 class B 中的 f() 是可选的。

Virtual keyword allows you to override functions not overload them.

Also, the virtual attribute is inherited so virtual keyword is optional for f() in class B.

够运 2024-11-13 03:07:55

当您将函数声明为 virtual 时,您真正对编译器说的是您希望该函数以多态方式运行。也就是说,从您的示例来看,如果我们有以下内容:

A* foo = new B();
foo->f();

它将调用 B 的“f”函数而不是 A 的“f”函数。更进一步,如果我们有一个像你所说的从 B 继承的 C:

class C : public B{}

B* foo = new C();
foo->f():

这称为 B 的“f”。如果你在 C 中定义它,它就会调用 C 的方法。

为了解释虚拟和非虚拟之间的不同行为,让我们举个例子:

struct Foo{
    virtual void f();
    void g();
};

struct Bar{
    virtual void f();
    void g();
};

Foo* var = new Bar();
var->f(); //calls Bar's f
var->g(); //calls Foo's g, it's not virtual

有意义吗?

When you declare a function virtual what you are really saying to the compiler is that you want this function to behave in a polymorphic manner. That is, from your example if we have the following:

A* foo = new B();
foo->f();

it will call B's "f" function and not A's "f" function. To take it further, if we have a C which inherits from B like you've said:

class C : public B{}

B* foo = new C();
foo->f():

this calls B's "f". If you had defined it within C, it would have called C's method.

To explain the different behavior between virtual and non-virtual let's take this example:

struct Foo{
    virtual void f();
    void g();
};

struct Bar{
    virtual void f();
    void g();
};

Foo* var = new Bar();
var->f(); //calls Bar's f
var->g(); //calls Foo's g, it's not virtual

make sense?

她说她爱他 2024-11-13 03:07:55

由于 A::f 是虚拟的,并且 B::f 具有相同的签名,因此可以说 B::f 覆盖 A::f。

这意味着:

A * p = new B;
p->f(); // invokes B::f

编辑:以下是完全错误的(请参阅注释):

由于 B::f 也是虚拟的,因此 B 的子类可以再次覆盖它。如果 B:f 不是虚拟的,那么子类中具有相同签名的任何方法都会简单地隐藏它(也就是说,它将是一个不同的方法)。

因此,行为取决于父级。

Since A::f is virtual, and B::f has the same signature, it is said that B::f overrides A::f.

Which means:

A * p = new B;
p->f(); // invokes B::f

EDIT: The following is just plain wrong (see the comments):

Since B::f is also virtual, then it would be possible for a child class of B to override it again. If B:f wasn't virtual, than any method with the same signature in a child class would simply shadow it (that is, it would be a different method).

So, the behaviors depends on the parent.

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