Sunday, June 13, 2010

const casting

The "const_cast" keyword.
  • Operates on references and pointers only.
  • When casting into a const the type is simply set as const.
  • When casting out of a const on a fundamental data type a copy of the variable is made on the FIRST local removal of the const only. This is to move the variable from the um-manipulable BSS/data segment into the current stack area.
  • When casting out the const on class the const status is simply removed and the object becomes directly modifiable.

//compile with g++
#include <iostream>
using namespace std;

class BaseA
{
public:
  int a;

  BaseA()         {a = 0;   cout << "BaseA create" << endl; }
  BaseA(BaseA& o) {a = o.a; cout << "BaseA copy" << endl; }
};

void print(int& a)
{ 
  cout << "print(int a) step1:" << a++ << endl; 
  cout << "print(int a) step2:" << a++ << endl; 
}

void print(int* a)
{ 
  cout << "print(int a) step1:" << (*a)++ << endl; 
  cout << "print(int a) step2:" << (*a)++ << endl; 
}

void print(const int& a)
{ cout << "print(const int a):" << a << endl; }

void print(BaseA& a)
{ 
  cout << "print(BaseA& a) step1:" << a.a++ << endl; 
  cout << "print(BaseA& a) step2:" << a.a++ << endl; 
}

void print(const BaseA& a) 
{ cout << "print(const BaseA& a):" << a.a << endl; }


int main()
{
  int       int1 = 100;
  const int int2 = 200;
  
  //print(const_cast<const int>(int1)); //BAD only works on pointers and references
  //print(const_cast<int>(int2));       //BAD only works on pointers and references

  cout << "const references" << endl;
  const int& refInt1 = const_cast<const int&>(int1); 
  int&       refInt2 = const_cast<int&>(int2);  //OK but get the value from the BSS and load it into the stack   

  refInt2++;
  print(refInt1); 
  print(refInt2); 

  cout << "Original: int1 = 100; is NOW: "  << int1 << endl;
  cout << "Original: int2 = 200; is NOW: "  << int2 << endl;

  cout << "Cast: refInt1; is NOW: "  << refInt1 << endl;
  cout << "Cast: refInt2; is NOW: "  << refInt2 << endl;
  cout << endl;

  cout << "const pointers" << endl;
  int*       ptrInt2 = const_cast<int*>(&int2);  //OK but get the item was already loaded in to the stack
  cout << "Cast: ptrInt2; is NOW: "  << *ptrInt2 << endl;

  print      (ptrInt2); 

  cout << "Original: int2 = 200; is NOW: "  << int2 << endl;
  cout << "Cast: ptrInt2; is NOW: "  << *ptrInt2 << endl;

  cout << endl;

  cout << "const classes" << endl;
  BaseA       a1;
  const BaseA a2;

  const BaseA& refA1 = const_cast<const BaseA&>(a1);
  BaseA&       refA2 = const_cast<BaseA&>(a2);  

  refA2.a++;
  print(refA1); 
  print(refA2); 

  cout << "Original: a1.a = 0; is NOW: "  << a1.a << endl;
  cout << "Original: a2.a = 0; is NOW: "  << a2.a << endl;

  cout << "Cast: refA1.a; is NOW: "  << refA1.a << endl;
  cout << "Cast: refA2.a; is NOW: "  << refA2.a << endl;
}

No comments:

Post a Comment