0
#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);
}

So right now I have the above code that focuses on inheritance and polymorphism. I need some help with understanding how parts of the outputs are achieved.

The outputs are:

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()

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()

and

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

Also could someone please explain to me how the TestFuncRef and TestFuncVal functions work? I don't get the outputs from those calls either. Thank you so much.

ALLISWELL
  • 19
  • 3

1 Answers1

1

The calling code is:

C c;
TestFuncRef(c);

And TestFuncRef upcasts C to Base and performs the following:

x.Func1();
x.Func2();
x.Func3();
x.Func4();
  1. Base::Func1 is virtual and C::Func1 overrides it
    • outputs "Hello from C::Func1()"
  2. Base::Func2 is virtual and C::Func2 is NOT implemented but C inherits from B and B::Func2 overrides it
    • outputs "Hello from B::Func2()"
  3. Base::Func3 is virtual and C::Func3 is NOT implemented but C inherits from B which inherits from A which inherits from Base and Base::Func3 is implemented
    • outputs "Hello from Base::Func3()"
    • THEN CALLS Func1 which is virtual (this is the same case as #1)
      • outputs "Hello from C::Func1()"
  4. Base::Func4 is NOT virtual therefore Base::Func4 is called (not C::Func4)
    • outputs "Hello from Base::Func4()"

Therefore the expected output is:

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

This is the exactly the first part of your output and is expected.

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()

This is exactly what it was told to do and your question seems to indicate you know something like this is expected as it includes the following.

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

Which obviously performs a Func1 operation during the Func3 operation and in this case produces the output you observe.

please explain to me how the TestFuncRef and TestFuncVal functions work

TestFuncRef is explained above.

TestFuncRef(b);

You should be able to trace this yourself in the same way as shown above.

TestFuncVal(c);

This introduces object slicing:

Edit

Your base class (Base) needs a virtual destructor (virtual ~Base()), see When to use virtual destructors?.

Community
  • 1
  • 1
James Adkison
  • 8,891
  • 2
  • 25
  • 39