In my example:

At upcasting, shouldn't the second `d.print()` call print "base"?

Isn't it "d" derived object upcasted to a base class object?

And at downcasting, what advantages does it have?

Could you explain upcast and downcast in a practical way?

```
#include <iostream>
using namespace std;

class Base {
public:
    void print() { cout << "base" << endl; }
};

class Derived :public Base{
public:
    void print() { cout << "derived" << endl; }

};

void main()
{
    // Upcasting
    Base *pBase;
    Derived d;
    d.print();
    pBase = &d;
    d.print();

    // Downcasting
    Derived *pDerived;
    Base *b;
    pDerived = (Derived*)b;
}

```