usingnamespace std;
class Base
{
int a;
public:
virtualvoid result(){cout<<"in base\n";}
};
class Derived : public Base
{
public:
int b;
Derived(int c):b(c){}
void result(){cout<<b<<endl;}
};
int main()
{
Base * pB = new Derived(3); // upcast
cout<<pB->b<<endl; // here error: ‘class Base’ has no member named ‘b’
pB->result(); // here there is no error? what is the reason, b could be visited by function ,not by ->? delete pB;
return 0;
}
what is the reason for the difference between lines22 and 23?
if there is upcast, the object pointed by the base class pointer is not a class deprived object any more? it will become a base class object?
You are creating an object of type Derived. The object is of type Derived no matter what you cast it to. Therefore, even though pB is a Base* pointer, it really points to a Derived object.
However, because the Base* pointer is a Base* pointer and not a Derived* pointer, you can only "see" stuff that is declared in Base. After all, Base* could, in theory, point to something else (like a true Base, or some other derived class besides Derived). Therefore you cannot call anything in Derived with a Base* pointer.
Polymorphism comes into play here because you're using a virtual function. A virtual function will use the actual type's version of the function, rather than the pointer type's version of the function. Therefore, because 'pB' points to a Derived, calling pB->result() actually calls Derived::result(). However, were this function not virtual, it would call Base::result().
'b' can be seen inside of Derived::result() because 'b' is part of Derived, and therefore all Derived members can see it.
The object is still of type Derived as mentioned above. You can cast it back
1 2
Derived* pD = (Derived*)pB;
cout << pD->b << endl; /* This should work */
and you should be able to access the derived members. I am not sure about the performance of the cast above. You may have to do a static_cast or dynamic_cast.