将调用C ++中的哪个虚函数

时间:2014-01-27 07:18:06

标签: c++

class A
{
    int a;
public:
    A()
    {
    }
    virtual void f1()
    {
        cout<<"A "<<endl;
    }
    virtual void f2()
    {
        f1();
    }
};

class B: public A
{
    int b;
public:
    B()
    {
    }
    void f1()
    {
        cout<<"B "<<endl;
    }
};

int main(void)
{
    B obj;
    obj.f2();
}

o / p - B

我在visual studio 2010上运行此代码。 请解释为什么要调用B类的函数f1()?为什么不是A类的函数f1()。

6 个答案:

答案 0 :(得分:0)

您正在使用B类型的对象。由于 f2()未被覆盖,它会调用A类的 f2(),它是超类。但是,因为 f1()已在B类中被覆盖,它将从 f2()调用B的 f1()而不是A A。

答案 1 :(得分:0)

对虚函数的每次调用都将执行虚函数查找并调用相应的实现。

所以你的例子中的调用结构是

obj.f2() -> Call A.f2(), because B has no overridden f2
in A.f2(), we call f1() -> This calls B.f1() because B overrides f1.

如果您明确希望在A.f2中静态调用A.f1,请使用A :: f1()。但是,你不应该这样做,因为它违背了在A中使用虚方法f1的想法。

答案 2 :(得分:0)

A课程中,f1f2都是虚拟的。这意味着任何子类都可以使用自己的实现覆盖它们。在main函数中,构造一个B类型的对象。当你调用函数时,它将调用B中的重写函数。该函数的调用者是谁 - 只是对象的类型是什么并不重要。在这种情况下,对象的类型为B。内部A::f2() this指向B类型的对象,因此会调用B::f1()。如果您有A* b = new B(); b->f2()

,这将以相同的方式工作

答案 3 :(得分:0)

virtual关键字表示该方法可以动态方式重写
由于该对象属于B类型,并且f1中的B重写,因此它将被调用。

答案 4 :(得分:0)

在基类中声明的虚函数会自动使所有相同名称的派生类成员函数也是虚拟的,即使它稍后未在派生类中声明为虚拟。所以在这种情况下,将调用b.f1()。

但是,如果从A的构造函数调用f1(),则不会发生这种情况,因为此时B尚未构造,并且未设置虚函数表。

答案 5 :(得分:0)

它调用B :: f1,因为它会覆盖A :: f1。你可以这样做来代替A:s方法:

int main(void)
{
  B obj;
  obj.f2();
  obj.A::f1();
}

或者:

virtual void f2()
{
  A::f1();
}