Typecasting is frequently used in C++ programming. Typecasting is used to tell the compiler that, even though the object is of one type, treat the object like some other type.
C++ provides the below types for casting
Casting Operators : dynamic_cast
Syntax : dynamic_cast <type> (Expression)
dynamic_cast operator is used to obtain the pointer to the deriverd class.
- dynamic_cast is a keyword.
- type is a pointer / reference to a previously defined class, it could also be a pointer to void.
- Expression if a pointer if the type is a pointer or it could be a l-value if the type is a reference.
Dynamic Casting |
---|
The dynamic_cast is used for - A safe casting from a base class pointer to a derived class pointer. Derived * ptr_derived = dynamic_cast < Derived * > ( ptr_base ). This is often referred as safe down-casting and is also another way of finding out the run time type information ( RTTI ) of the pointer / reference. If the dynamic_cast is successful, the derived class pointer points to the object of derived class. In case of a failure, the derived class pointer points to NULL. - A safe casting from an l-value of a base class type to a reference to a derived class type. Derived & ref_derived = dynamic_cast < Derived & > ( ref_base ). On success of the dynamic_cast, the derived class reference will refer to the object that the base class reference is referring to. In case of a failure, an exception of type bad_cast is thrown. |
Casting Operators : static_cast |
---|
Syntax : static_cast <type> (Expression) static_cast operator is used for making any conversion explicit which compiler performs implicitly. - static_cast is a keyword. - type is a built_in or a user defined type. - Expression is a built_in or a user defined type. |
The static_cast works in a similar manner to the traditional typecasting i.e it converts the expression to the data type of the type.
static_cast does not check the run-time type (of to and from) to ensure the safety during the conversion.
C++ program to demonstrate dynamic_cast & static_cast.
#include<iostream>
using namespace std;
class Employee {
public:
virtual void Get_Salary () = 0;
};
class Software_Engineer : public Employee {
public:
void Get_Salary () {
cout << "Software Engineer's salary : $ 100000" << endl;
}
};
class Engineering_Manager : public Employee {
public:
void Get_Salary () {
cout << "Engineering Manager's salary : $ 250000" << endl;
}
};
class Vice_President : public Employee {
public:
void Get_Salary () {
cout << "Vice President Engineering : $ 400000" << endl;
}
};
void PayRoll (Employee & emp) {
// Note : If the dynamic cast in unsuccessful, an exception of type bad_cast is thrown.
try {
Software_Engineer& se = dynamic_cast<Software_Engineer&>(emp);
se.Get_Salary();
} catch (bad_cast b) {
cout << "Exception : " << b.what() << endl;
}
try {
Vice_President& vp = dynamic_cast<Vice_President&>(emp);
vp.Get_Salary();
} catch (bad_cast b) {
cout << "Exception : " << b.what() << endl;
}
}
int main() {
Employee * Employee_ptr = new Software_Engineer;
// Get Engineering Manager's salary using static cast
// Note : No run-time type check is done to ensure the safety of the conversion.
Engineering_Manager * mgr_ptr_1 = static_cast<Engineering_Manager*> (Employee_ptr);
mgr_ptr_1->Get_Salary(); // Incorrectly get's Software Engineer's salary.
// Get Engineering Manager's salary using dynamic cast
Engineering_Manager * mgr_ptr_2 = dynamic_cast<Engineering_Manager*> (Employee_ptr);
if (mgr_ptr_2) {
mgr_ptr_2->Get_Salary();
} else {
cout << "Pointer is NULL. Casting invalid" << endl;
}
Engineering_Manager mgr;
Software_Engineer se;
Vice_President vp;
PayRoll(vp);
return 0;
}
Output
Software Engineer's salary : $ 100000
Pointer is NULL. Casting invalid
Exception : std::bad_cast
Vice President Engineering : $ 400000