The "static_cast" keyword.
- Operates on references and pointers of class and on the inbuilt data types and class with conversion constructors.
- In the case of inbuilt data types it converts the value into the new type.
- In the case of conversion constructor classes, it creates a new object from the original object using the conversion constructor. Note that copy constructors ARE conversion constructors and WILL be implicitly apply to any derived class.
- In the case of pointers and references:
- The cast confirms at compile time that the pointers convert from and to are are related by inheritance, ie they share the same Base class a some point.
- Since the cast performs no RTTI check the it is faster and lighter than the "dynamic_cast".
- If used badly on pointers or references it can convert invalidly, for example a base class can be converted to a Derived class despite the fact that it wont have memory for the derived classes member variables.
//compile with g++
#include <iostream>
using namespace std;
class BaseA
{
virtual void print() { cout << "BaseA"; }
};
class DerivedA1 : public BaseA
{
int a;
virtual void print() { cout << "DerivedA1"; }
};
class DerivedA2 : public BaseA
{
virtual void print() { cout << "DerivedA2"; }
};
class DerivedA3 : public DerivedA1
{
virtual void print() { cout << "DerivedA3"; }
};
class BaseB
{
public:
BaseB() { }
BaseB(BaseA& A) { cout << "Converting BaseA" << endl; }
virtual void print() { cout << "BaseA"; }
};
int main()
{
int int1 = 100;
double double1 = 3.142;
cout << "static casting: inbuilt datatypes " << endl;
char char1 = static_cast<char>(int1);
int int2 = static_cast<int>(double1);
BaseA* base1 = new BaseA();
BaseB* baseB = new BaseB();
BaseA* base2 = new DerivedA2();
BaseA* base3 = new DerivedA3();
DerivedA3* derived1 = new DerivedA3();
cout << "static_cast<char>(int1) " << char1 << " <- " << int1 << endl;
cout << "static_cast<int>(double) " << int2 << " <- " << double1 << endl;
cout << endl;
cout << "static casting: conversion constructor classes " << endl;
BaseB objB = static_cast<BaseB>(*base1);
BaseA objA1 = static_cast<BaseA>(*base2); //OK the default copy constructor IS a conversion constructor
//BaseA objA2 = static_cast<BaseA>(*baseB); //BAD no conversion constructor
cout << "static casting: pointers " << endl;
DerivedA1* derived2 = static_cast<DerivedA1*>(base1); //BAD base1 doesnt have the correct memory to be DerivedA1 class!
DerivedA1* derived3 = static_cast<DerivedA1*>(base2);
DerivedA2* derived4 = static_cast<DerivedA2*>(base2);
DerivedA1* derived5 = static_cast<DerivedA1*>(base3);
BaseA* base4 = static_cast<BaseA*>(derived1); //OK but overkill
//char* charPtr = static_cast<char*>(&int1); //BAD int and char dont share any inhertance.
//BaseB* base5 = static_cast<BaseB*>(derived1); //BAD BaseB and dervied1 dont share any inhertance.
cout << "static casting: references " << endl;
DerivedA1& refDerived1 = static_cast<DerivedA1&>(*base1); //BAD base1 doesnt have the correct memory to be DerivedA1 class!
DerivedA1& refDerived2 = static_cast<DerivedA1&>(*base2);
DerivedA2& refDerived3 = static_cast<DerivedA2&>(*base2);
DerivedA1& refDerived4 = static_cast<DerivedA1&>(*base3);
BaseA& refBase = static_cast<BaseA&>(*derived1);
//BaseB& refBaseB = static_cast<BaseB&>(*derived1); //BAD BaseB and dervied1 dont share any inhertance.
delete base1;
delete baseB;
delete base2;
delete base3;
delete derived1;
}
No comments:
Post a Comment