The "reinterpret_cast" keyword.
- Operates on references and pointers.
- It results in only the direct coping of the pointer/reference and nothing more. This means that the exact value being pointed to is unchanged and will be interpreted as the new type directly.
- The exact way the contents of the pointer are interpreted after conversion is very system dependent.
- This cast is normally used to convert c++ data structures into something usable by a 3rd party API or lib, or in buffer pools and variable data type implementations. If a chunk of data has multiple interpretations to (like IP headers etc) then a "union" is better choice.
//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 << "reinterpret casting: non-conversion of data example " << endl;
char* char1 = reinterpret_cast<char*>(&int1); //OK keep in mind the endianess of the system
int* int2 = reinterpret_cast<int*>(&double1); //OK be aware of the proceses native double formats
cout << "reinterpret_cast<char>(int1) " << *char1 << " <- " << int1 << endl;
cout << "reinterpret_cast<int>(double) " << *int2 << " <- " << double1 << endl;
cout << endl;
BaseA* base1 = new BaseA();
BaseB* baseB = new BaseB();
BaseA* base2 = new DerivedA2();
BaseA* base3 = new DerivedA3();
DerivedA3* derived1 = new DerivedA3();
cout << "reinterpret casting: pointers " << endl;
DerivedA1* derived2 = reinterpret_cast<DerivedA1*>(base1); //BAD base1 doesnt have the correct memory to be DerivedA1 class!
DerivedA1* derived3 = reinterpret_cast<DerivedA1*>(base2);
DerivedA2* derived4 = reinterpret_cast<DerivedA2*>(base2);
DerivedA1* derived5 = reinterpret_cast<DerivedA1*>(base3);
BaseA* base4 = reinterpret_cast<BaseA*>(derived1); //OK but overkill
char* charPtr = reinterpret_cast<char*>(&int1); //OK but be careful int and char dont share any inhertance.
BaseB* base5 = reinterpret_cast<BaseB*>(derived1); //BAD BaseB and dervied1 have conflicting memory layouts
cout << "reinterpret casting: references " << endl;
DerivedA1& refDerived1 = reinterpret_cast<DerivedA1&>(*base1); //BAD base1 doesnt have the correct memory to be DerivedA1 class!
DerivedA1& refDerived2 = reinterpret_cast<DerivedA1&>(*base2);
DerivedA2& refDerived3 = reinterpret_cast<DerivedA2&>(*base2);
DerivedA1& refDerived4 = reinterpret_cast<DerivedA1&>(*base3);
BaseA& refBase = reinterpret_cast<BaseA&>(*derived1);
BaseB& refBaseB = reinterpret_cast<BaseB&>(*derived1); //BAD BaseB and dervied1 have conflicting memory layouts
delete base1;
delete baseB;
delete base2;
delete base3;
delete derived1;
}
No comments:
Post a Comment