jweinst1
8/14/2017 - 11:46 PM

unsafetyping.cpp

#include <iostream>

//c++ example using reinterpret_cast to facilitate dynamic type systems

#define Base_HANDLE int type; \
               struct Base* next; \
               struct Base* prev; 

class Base
{
  protected:
  //this must always be first
   Base_HANDLE
   bool state;
   public:
   int getType()
   {
     return type;
   }
};

//intobj doesn't have getType, but can use the method since it has 
//the type property 

//inheritance guarantees the Base object methods are first
class IntObj :public Base
{
  public:
  static IntObj* instance(long value)
  {
    IntObj* iobj = new IntObj();
    iobj->value = value;
    iobj->type = 6;
    return iobj;
  }
  
  //added property
    long value;
    long getValue()
    {
      return value;
    }
    bool getState()
    {
      return state;
    }
    
    
};

class CharObj: public Base
{
  public:
  char letter;
  static CharObj* instance(char letter)
  {
    CharObj* cobj = new CharObj();
    cobj->letter = letter;
    cobj->type = 4;
    return cobj;
  }
  
  //adds new getter method
  char getLetter()
  {
    return letter;
  }
  
  void setLetter(char l)
  {
    letter = l;
  }
};



int main() {
    IntObj* i = IntObj::instance(500);
    Base* b = reinterpret_cast<Base*>(i);
    std::cout << b->getType() << std::endl;
    //3
    std::cout << b->getType() << std::endl;
    //3
    

    
    IntObj* j = reinterpret_cast<IntObj*>(b);
    std::cout << j->getState() << std::endl;
    //1
    std::cout << j->getValue() << std::endl;
    //500
    IntObj* h = IntObj::instance(8);
    std::cout << j->getValue() << std::endl;
    /*Getter methods work due to same byte offset*/
    delete i;
    
    CharObj* cobj = CharObj::instance('a');
    Base* d = reinterpret_cast<Base*>(cobj);
    std::cout << d->getType() << std::endl;
    //4
    CharObj* e = reinterpret_cast<CharObj*>(d);
    std::cout << e->getLetter() << std::endl;
    //t
    
    e->setLetter('$');
    std::cout << e->getLetter() << std::endl;
    //$
    delete cobj;
}