Wednesday, 26 November 2014

Upcasting and Downcasting in C++ with examples

What is Upcasting and Downcasting in c++?

Upcasting:

First we will look into the upcasting. Converting the derived class pointer to the base class pointer or converting the derived class reference to the base class reference is called as upcasting. It allows public inheritance without the need for an explicit type cast.

A Derived object is-a relationship with the base class. The derived class can get the properties of base class, nothing but it can inherit the data members and member function of the base class.

Means, anything that we can do to a Base object, we can do to a Derived class object.

Downcasting:

Downcasting is exactly opposite to the upcasting the opposite of upcasting. is a process converting a base-class pointer or reference to a derived-class pointer or reference.

It should possible with the explicit type conversion. Because a derived class could add new data members, and the class member functions that used these data members wouldn't apply to the base class.

Let us look into the small example which will give us clear picture about the upcasting and down casting
#include <iostream>
using namespace std;

class MyPrince { 

private:
 int id;

public:
 void DispId () {

    cout << "I am in the principle class" << endl; 
  }
};

class MyStuent : public MyPrince {

public:

 void Disaply () {
    
    cout << "I am in the MyStudent class" << endl;
  }
};

int _tmain (int argc, _TCHAR* argv[])
{

 MyPrince ocPrince;
 MyStuent ocStuent;

 // upcast - implicit upcast allowed
 MyPrince *prince = &ocStuent;

 // downcast - explicit type cast required
 MyStuent *pcStudent = (MyStuent *)&ocPrince;

 // Upcasting: safe - 
 prince->DispId ();
 pcStudent->DispId ();

 // Downcasting: unsafe - 
  pcStudent->Disaply(); 

  getchar ();
  return 0;
} 
The output of the above program is:
I am in the principle class

I am in the principle class

I am in the MyStudent class

The typeid in C++:

If we want to find the two objects are of the same type, we will have the option of typeid. Using the typeid we will find the type of the object.

In the previous example for Upcasting and Downcasting, MyStudent gets the method Disaply() which is not desirable. So, we need to check if a pointer is pointing to the MyStudent object before we use the method, Disaply ().

Note that we included <typeinfo> in the example. The typeid operator returns a reference to a type_info object, where type_info is a class defined in the typeinfo header file.

Here is a new code showing how to use typeid:
 #include <typeinfo>

 class Principle { 
private:
 int id;
public:
 void DispId()  {    cout << "I am in the Principle class" << endl;}
};

class MyStudent : public Principle {
public:
 void Disaply() {    cout << "I am in the MyStudent class" << endl; }
};


int main() 
{
 Principle ocPrince;
 MyStudent ocStudent;

 Principle *pcPri = &ocPrince;
 Principle *pcPri2 = &ocStudent;

 // check if two object is the same
 if(typeid(MyStudent) == typeid(ocPrince)) {
  MyStudent *pProg = (MyStudent *)&ocPrince; 
  pProg->Disaply();
 }
 if(typeid(MyStudent) == typeid(ocStudent)) {
  MyStudent *pProg = (MyStudent *)&ocStudent; 
  pProg->Disaply();
 }

 pcPri->DispId();
 pcPri2->DispId();
getchar ();
 return 0;
}
The output of the above program is:
I am in the MyStudent class
I am in the Principle class
I am in the Principle class
So, only a MyStudent uses the Disaply () method.

1 comment:

Kipp Monnix said...

...needs some editing.

Also for upcasting it's recommending to use dynamic_cast (especially true when you're dealing with objects with multiple inheritence).

"(MyStuent *)&ocPrince" should be:
"dynamic_cast(&ocPrince)"

Thanks for covering this topic!