TYPECASTING IN C++ (DYNAMIC_CAST, STATIC_CAST, REINTERPRET_CAST, CONST_CAST)
TYPE CASTING:
Explicit type casting between classes have four specific casting operators:
1) dynamic_cast<new_type> (expression)
2) static_cast<new_type> (expression)
3) reinterpret_cast<new_type> (expression)
4) const_cast<new_type> (expression)
Explicit type casting between classes have four specific casting operators:
1) dynamic_cast<new_type> (expression)
2) static_cast<new_type> (expression)
3) reinterpret_cast<new_type> (expression)
4) const_cast<new_type> (expression)
1) Dynamic Cast:
a) dynamic_cast can be used only with pointers and references to objects.
b) Its purpose is to ensure that the result of the type conversion is a valid complete object of the requested class.
c) When dynamic_cast cannot cast a pointer because it is not a complete object of the required class, it returns a null pointer to indicate the failure.
class CBase {};
class CDerived : public CBase {};
CBase b; CBase* pb;
CDerived d; CDerived* pd;
pb = dynamic_cast<CBase*>(&d); //ok; derived-to-base
pd = dynamic_cast<CDerived*>(&b); //wrong; base-to-derived
2) Static Cast:
static_casT can perform conversions between pointers to related classes,
not only from the derived class to its base,
but also from a base class to its derived.
class CBase {};
class CDerived : public CBase {};
CBase* a = new CBase;
CDerived* b = static_cast<CDerived*>(a);
3) Reinterpret Cast:
reinterpret_cast converts any pointer type to any other pointer type, even of unrelated classes.
class A {};
class B {};
A* a = new A;
B* b = reinterpret_cast<B*>(a);
4) Const cast:
This type of casting manipulates the constness of an object, either to be set or to be removed.
TypeID:
typeid allows to check the type of an expression.
typeid(expression)
Example:
class A
{
public:
int a;
A() {}
A(int aa)
{
a = aa;
}
virtual void Display()
{
cout << "A::Display" << endl;
cout << "A = " << a << endl;
}
virtual void PrintConstCast(char* str)
{
cout << "A - String: " << str << endl;
}
};
class B : public A
{
public:
int b;
B(int a, int b)
{
this->a = a;
this->b = b;
}
void Display()
{
cout << "B::Display" << endl;
cout << "A = " << a << endl;
cout << "B = " << b << endl;
}
void PrintConstCast(char* str)
{
cout << "B - String: " << str << endl;
}
};
int main()
{
cout << "Hello World!\n";
A* pA = new A(1);
pA->Display();
pA->PrintConstCast(const_cast<char*>("string"));
cout << "typeid of pA " << typeid(pA).name() << endl;
cout << endl;
B* pB = new B(11, 111);
pB->Display();
pB->PrintConstCast(const_cast<char*>("string"));
cout << "typeid of pB " << typeid(pB).name() << endl;
cout << endl;
cout << "Dynamic cast" << endl;
B* pDyn1 = dynamic_cast<B*>(pA);
if (pDyn1)
{
pDyn1->Display();
cout << "typeid of pDyn1 " << typeid(pDyn1).name() << endl;
}
else
cout << "pDyn is not a whole object" << endl;
cout << endl;
cout << "Static cast" << endl;
B* pDyn2 = static_cast<B*>(pA);
if (pDyn2)
{
pDyn2->Display();
cout << "typeid of pDyn2 " << typeid(pDyn2).name() << endl;
}
cout << endl;
cout << "Reinterpret cast" << endl;
B* pDyn3 = reinterpret_cast<B*>(pA);
if (pDyn3)
{
pDyn3->Display();
cout << "typeid of pDyn3 " << typeid(pDyn3).name() << endl;
}
cout << endl;
return -1;
}