【问题标题】:Which virtual function in C++ will be called [duplicate]C ++中的哪个虚函数将被调用[重复]
【发布时间】:2014-01-27 07:18:05
【问题描述】:
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 stdio 2010 上运行此代码。 请解释为什么调用 B 类的函数 f1()?为什么不是 A 类的函数 f1()。

【问题讨论】:

  • 因为你没有调用Af1函数
  • 因为 f1 在 A 中是 virtual,在 B 中被覆盖。您使用的是 B 类型的对象。

标签: c++


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    每个对虚函数的调用都会进行虚函数查找并调用相应的实现。

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

    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 的想法。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        virtual 关键字表明该方法可以动态方式被覆盖
        由于该对象的类型为B,并且由于f1B 中被覆盖,它将被调用。

        【讨论】:

          【解决方案5】:

          在基类中声明的虚函数自动使所有同名的派生类成员函数也成为虚函数,即使它后来没有在派生类中声明为虚函数。因此,在这种情况下,将调用 b.f1()。

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

          【讨论】:

            【解决方案6】:

            它调用 B::f1 是因为它覆盖了 A::f1。您可以这样做来调用 A:s 方法:

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

            或者:

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

            【讨论】:

              猜你喜欢
              • 2013-09-21
              • 1970-01-01
              • 2015-09-29
              • 1970-01-01
              • 1970-01-01
              • 2013-07-30
              • 2013-02-18
              • 2012-03-20
              • 2017-08-13
              相关资源
              最近更新 更多