C++ 继承和多态未知输出

C++ Inheritance and Polymorphism unknown output

#include "stdafx.h"
#include <iostream>
using namespace std;
class Base
{ // Define a base class
public:
    virtual void Func1() = 0;
    virtual void Func2();
    virtual void Func3();
    void Func4();
};
class A : public Base
{ // Class A derives from Base
public:
    void Func2();
    virtual void Func4();
};
class B : public A
{// Class B derives from A
public:
    virtual void Func1();
    void Func2();
};
class C : public B
{ // Class C derives from B
public:
    virtual void Func1();
    virtual void Func4();
};
// Base Class Methods
void Base::Func2(){ cout << "Hello from Base::Func2()" << endl;}
void Base::Func3(){cout << "Hello from Base::Func3()" << endl;
Func1(); // DON’T MISS THIS CALL IN YOUR ANSWER
}
void Base::Func4(){ cout << "Hello from Base::Func4()" << endl;}
// Class A Methods
void A::Func2() { cout << "Hello from A::Func2()" << endl; }
void A::Func4() { cout << "Hello from A::Func4()" << endl; }
// Class B Methods
void B::Func1() { cout << "Hello from B::Func1()" << endl; }
void B::Func2() { cout << "Hello from B::Func2()" << endl; }
// Class C Methods
void C::Func1() { cout << "Hello from C::Func1()" << endl; }
void C::Func4() { cout << "Hello from C::Func4()" << endl; }
void TestFuncRef(Base& x)
{
    x.Func1();
    x.Func2();
    x.Func3();
    x.Func4();
}
void TestFuncVal(B x)
{
    x.Func1();
    x.Func2();
    x.Func3();
    x.Func4();
}
int main()
{
    B b;
    C c;
    TestFuncRef(c);
    TestFuncRef(b);
    TestFuncVal(c);
}

所以现在我有上面的代码专注于继承和多态性。我需要一些帮助来理解部分输出是如何实现的。

输出是:

Hello from C::Func1()
Hello from B::Func2()
Hello from Base::Func3()
Hello from C::Func1()
Hello from Base::Func4()
Hello from B::Func1()
Hello from B::Func2()
Hello from Base::Func3()
Hello from B::Func1()
Hello from Base::Func4()
Hello from B::Func1()
Hello from B::Func2()
Hello from Base::Func3()
Hello from B::Func1()
Hello from A::Func4()

我不明白为什么在 base Func3 和 Base func4 调用之间总是有一些调用。比如下面

Hello from Base::Func3()
Hello from C::Func1()
Hello from Base::Func4()

Hello from Base::Func3()
Hello from B::Func1()
Hello from Base::Func4()

还有人可以向我解释一下 TestFuncRef 和 TestFuncVal 函数是如何工作的吗?我也没有从这些调用中得到输出。非常感谢。

调用代码为:

C c;
TestFuncRef(c);

并且 TestFuncRefC 向上转换为 Base 并执行以下操作:

x.Func1();
x.Func2();
x.Func3();
x.Func4();
  1. Base::Func1 是虚拟的,C::Func1 覆盖它
    • 输出"Hello from C::Func1()"
  2. Base::Func2 是虚拟的,C::Func2NOT 实现的,但是 C 继承自 BB::Func2覆盖它
    • 输出"Hello from B::Func2()"
  3. Base::Func3 是虚拟的,C::Func3NOT 实现的,但是 C 继承自 B,后者继承自 A 继承自 Base 并实现了 Base::Func3
    • 输出"Hello from Base::Func3()"
    • THEN CALLS Func1 这是虚拟的(这与#1 的情况相同)
      • 输出"Hello from C::Func1()"
  4. Base::Func4NOT 虚拟因此 Base::Func4 被调用(不是 C::Func4
    • 输出"Hello from Base::Func4()"

因此预期的输出是:

Hello from C::Func1()
Hello from B::Func2()
Hello from Base::Func3()
Hello from C::Func1()
Hello from Base::Func4()

这正是您输出的第一部分,符合预期。

I don't understand how there are always some call between the base Func3 and Base func4 calls. Such as the following.

Hello from Base::Func3()
Hello from C::Func1()
Hello from Base::Func4()

这正是它被告知要做的,你的问题似乎表明你知道这样的事情是预期的,因为它包括以下内容。

void Base::Func3(){cout << "Hello from Base::Func3()" << endl; Func1(); // DON’T MISS THIS CALL IN YOUR ANSWER }

这显然在 Func3 操作期间执行了 Func1 操作,在这种情况下会产生您观察到的输出。

please explain to me how the TestFuncRef and TestFuncVal functions work

TestFuncRef上面有解释

TestFuncRef(b);

您应该可以按照上面所示的相同方式自行追踪。

TestFuncVal(c);

这里介绍了对象切片:

编辑

您的基础 class (Base) 需要一个虚拟析构函数 (virtual ~Base()),请参阅 When to use virtual destructors?