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

时间:2011-05-06 11:13:54

标签: c++ polymorphism virtual

我是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()也被声明为虚拟,这是否意味着f()中的class B重载f()中的class A?是否允许继承B的类重载f()?或者B是否定义了与f()中的class A不同的新虚拟函数?

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

4 个答案:

答案 0 :(得分:4)

  在类B内部,函数f()也被声明为虚拟,所以这意味着类A中的f()在类A中重载f()

不,它没有重载。它覆盖。关键字virtual在类B中也是可选的。无论您是否撰写B::f()virtual始终都是virtual函数。

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

答案 1 :(得分:2)

虚拟关键字允许您 覆盖 功能而不是 重载

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

答案 2 :(得分:1)

当你声明一个虚函数时,你真正对编译器说的是你希望这个函数以多态方式运行。也就是说,如果我们有以下内容,请从您的示例中获取:

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

有意义吗?

答案 3 :(得分:0)

由于A :: f是虚拟的,而B :: f具有相同的签名,因此可以说B :: f 会覆盖 A :: f。 / p>

这意味着:

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

编辑:以下是完全错误的(见评论):

由于B :: f也是虚拟的,因此B的子类可能会再次覆盖它。如果B:f不是虚拟的,那么在子类中具有相同签名的任何方法都只会遮蔽它(也就是说,它将是一种不同的方法)。

因此,行为取决于父母。