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);
并且 TestFuncRef
将 C
向上转换为 Base
并执行以下操作:
x.Func1();
x.Func2();
x.Func3();
x.Func4();
Base::Func1
是虚拟的,C::Func1
覆盖它
- 输出
"Hello from C::Func1()"
Base::Func2
是虚拟的,C::Func2
是 NOT 实现的,但是 C
继承自 B
和 B::Func2
覆盖它
- 输出
"Hello from B::Func2()"
Base::Func3
是虚拟的,C::Func3
是 NOT 实现的,但是 C
继承自 B
,后者继承自 A
继承自 Base
并实现了 Base::Func3
- 输出
"Hello from Base::Func3()"
- THEN CALLS
Func1
这是虚拟的(这与#1 的情况相同)
- 输出
"Hello from C::Func1()"
Base::Func4
是 NOT 虚拟因此 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);
这里介绍了对象切片:
- Wikipedia - Object slicing
- Stack Overflow - What is object slicing?
编辑
您的基础 class (Base
) 需要一个虚拟析构函数 (virtual ~Base()
),请参阅 When to use virtual destructors?。
#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);
并且 TestFuncRef
将 C
向上转换为 Base
并执行以下操作:
x.Func1();
x.Func2();
x.Func3();
x.Func4();
Base::Func1
是虚拟的,C::Func1
覆盖它- 输出
"Hello from C::Func1()"
- 输出
Base::Func2
是虚拟的,C::Func2
是 NOT 实现的,但是C
继承自B
和B::Func2
覆盖它- 输出
"Hello from B::Func2()"
- 输出
Base::Func3
是虚拟的,C::Func3
是 NOT 实现的,但是C
继承自B
,后者继承自A
继承自Base
并实现了Base::Func3
- 输出
"Hello from Base::Func3()"
- THEN CALLS
Func1
这是虚拟的(这与#1 的情况相同)- 输出
"Hello from C::Func1()"
- 输出
- 输出
Base::Func4
是 NOT 虚拟因此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);
这里介绍了对象切片:
- Wikipedia - Object slicing
- Stack Overflow - What is object slicing?
编辑
您的基础 class (Base
) 需要一个虚拟析构函数 (virtual ~Base()
),请参阅 When to use virtual destructors?。