|< C++ Typecasting 1 | Main | Namespaces >| Site Index | Download |


 

 

 

 

 

MODULE 22 - C/C++ TYPECASTING ISSUES 2

Converting the different type of variable data including

the objects and classes either implicitly or explicitly in C & C++ programs

 

 

 

 

 

 

 

 

 

 

 

 

 

 

My Training Period: xx hours

 

More Typecasting Program Examples Using C++ Exception Class

 

// multiple inheritance, conversion using dynamic_cast

#include <iostream>

using namespace std;

 

// a base class

class Base1 { };

class Derived1:public Base1{ };

class Derived2:public Base1{ };

// a derived class...

class Derived3:public Derived1, public Derived2

{

       public:

           virtual void funct1(){ }

};

// a dynamic_cast test function...

void funct2()

{

       // instantiate an object…

       Derived3 *Test1 = new Derived3;

 

       // -------start comment out---------

       // may fail, ambiguous...from Derived3 direct

       // conversion to Base1...

       // if you use good compiler, please comment out this

       // part, there should be run time error:-)

       Base1* Test2 = dynamic_cast<Base1*>(Test1);

       cout<<"Base1* Test2 = dynamic_cast<Base1*>(Test1);"<<endl;

       if(!Test2)

              cout<<"The conversion is fail..."<<endl;

       else

              cout<<"The conversion is successful..."<<endl;

       // re-confirm the pointer

       cout<<"The pointer should be NULL ==> "<<Test2<<endl;

       // ---------end comment out----------

 

       // solution, traverse, recast, firstly, cast to Derived1

       Derived1* Test3 = dynamic_cast<Derived1*>(Test1);

       cout<<"\nDerived1* Test3 = dynamic_cast<Derived1*>(Test1);"<<endl;

       if(!Test3)

              cout<<"The conversion is fail..."<<endl;

       else

              cout<<"The conversion is successful..."<<endl;

 

       // then cast to base1....

       Base1* Test4 = dynamic_cast<Base1*>(Test3);

       cout<<"\nBase1* Test4 = dynamic_cast<Base1*>(Test3);"<<endl;

       if(!Test4)

              cout<<"The conversion is fail..."<<endl;

       else

              cout<<"The conversion is successful..."<<endl;

}

 

int main()

{

       funct2();

       return 0;

}

 

Output:

 

C++ Typecasting multi inheritance dynamic_cast program example

C++ Typecasting inheritance dynamic_cast crosscast program example

Figure 22.7:  Crosscast, from Base2 to Derived1

 

// testing the crosscast: downcast, upcast and crosscast

// conversion using dynamic_cast

#include <iostream>

using namespace std;

 

// a base class

class Base1

{

       public:

           virtual void funct1(){ };

};

// a derived class

class Derived1:public Base1

{

       public:

           virtual void funct2(){ };

};

// a derived class

class Derived2:public Base1{

       public:

           virtual void funct3(){ };

};

// a derived class...

class Base2

{

       public:

           virtual void funct4(){ };

};

// a derived class

class Derived3:public Derived1,public Derived2,public Base2

{ };

// dynamic_cast test function...

void funct5()

{

       // instantiate an object, Test1 of type Base2...

       // or test1 of type Derived2...you can choose either one      

       Base2* Test1 = new Base2;

       // Derived2* Test1 = new Derived2;

       // start with downcast, type Base2/Derived2 to Derived3...

       Derived3* Test2 = dynamic_cast<Derived3*>(Test1);

       cout<<"Firstly, Derived3* Test2 = dynamic_cast<Derived3*>(Test1);"<<endl;

       if(!Test2)

       {

              cout<<"The conversion is fail lor!"<<endl;

              cout<<"Checking the pointer = "<<Test2<<endl;

       }

       else

              cout<<"The conversion is successful..."<<endl;

       // upcast, type derived3 to type derived1...

       Derived1* Test3 = dynamic_cast<Derived1*>(Test2);

       cout<<"\nThen, Derived1* Test3 = dynamic_cast<Derived1*>(Test2);"<<endl;

       if(!Test3)

       {

              cout<<"The conversion is fail lor!"<<endl;

              cout<<"Checking the pointer = "<<Test3<<endl;

       }

       else

              cout<<"The conversion is successful..."<<endl;

       // crosscast, direct, type Base2/Derived2 to Derived1...

       Derived1* Test4 = dynamic_cast<Derived1*>(Test1);

       cout<<"\nThen, Derived1* Test4 = dynamic_cast<Derived1*>(Test1);"<<endl;

       if(!Test4)

       {

              cout<<"The conversion is fail lor!"<<endl;

              cout<<"Checking the pointer = "<<Test3<<endl;

       }             

       else

              cout<<"The conversion is successful..."<<endl;

       delete Test1;

}

 

int main()

{

       funct5();

       return 0;

}

 

Output:

 

C++ Typecasting inheritance so many cast program example

C++ Typecasting inheritance all cast program example

 

// a dynamic_cast ambiguous conversion experiment :o)

#include <iostream>

using namespace std;

 

// a class with virtual function, polymorphic…

class Base1

{

       public:

           virtual void FuncBase1()

           { };

};

// another class with virtual function...

class Base2

{

       public:

           virtual void FuncBase2()

           { };

};

// derived class from Base1 and Base2 classes

// public virtual and private...

class Derived1:public virtual Base1, private Base2

{ };

// a dynamic_cast test function...

void DynamicCastSample()

{

       // instantiate an object of type Derived1 class...

       Derived1 DerivedObj;

       // simple assignment, derived to base class, upcasting...

       // cast needed to break private protection...

       Base2* Base2Obj = (Base2*) &DerivedObj;

       // another assignment, derived to base class, upcasting...

       // public inheritance, no need casting..

       Base1* Base1Obj = &DerivedObj;

       // base class to derived class, downcast

       Derived1& Derived1Obj = dynamic_cast<Derived1&>(*Base2Obj);

       if(!&Derived1Obj)

              cout<<"Conversion is failed!...."<<endl;

       else

              cout<<"Conversion is OK...."<<endl;

       cout<<"The address.."<<&Derived1Obj<<endl;

       // base class to derived class, downcast

       Base1Obj = dynamic_cast<Base1*>(Base2Obj);

       if(!Base1Obj)

              cout<<"Conversion is failed!...."<<endl;

       else

              cout<<"Conversion is OK...."<<endl;

       cout<<"The address.."<<Base1Obj<<endl;

       // base class to base class, ????

       // no inheritance…

       Base2Obj = dynamic_cast<Base2*>(Base1Obj);

       if(!Base2Obj)

              cout<<"Conversion is failed!...."<<endl;

       else

              cout<<"Conversion is OK...."<<endl;

       cout<<"The address.."<<Base2Obj<<endl;

       // derived class to base class, upcast

       Base1Obj = dynamic_cast<Base1*>(&Derived1Obj);

       if(!Base1Obj)

              cout<<"Conversion is failed!...."<<endl;

       else

              cout<<"Conversion is OK...."<<endl;

       cout<<"The address.."<<Base1Obj<<endl;

       // derived class to base class...

       // Derived1Obj is derived from non-virtual, private Base2…

       Base2Obj = dynamic_cast<Base2*>(&Derived1Obj);

       if(!Base2Obj)

              cout<<"Conversion is failed!...."<<endl;

       else

              cout<<"Conversion is OK...."<<endl;

       cout<<"The address.."<<Base2Obj<<endl;

}

 

int main()

{

       int *ptr = NULL;

       int var;

 

       cout<<"Benchmarking..."<<endl;

       cout<<"Address of var = "<<&var<<endl;

       // NULL pointer

       cout<<"NULL *ptr = "<<ptr<<endl;

       cout<<endl;

       // call the function for dynamic_cast testing...

       DynamicCastSample();

       return 0;

}

 

Output:

 

C++ Typecasting inheritance dynamic_cast program example

 

22.5  rtti

RTTI element

Brief description

dynamic_cast

Polymorphic types conversion.

typeid() operator              

Used to identify the exact type of an object.

type_info class

Used for holding the type information returned by the typeid operator.

 

Table 22.2: RTTI elements

typeid( expression )

typeid( type_name )

 

// using typeid operator, type_info::before()

// and type_info::name() member functions

#include <iostream>

#include <typeinfo>

using namespace std;

 

// T - True, F - False

#define T 1

#define F 0

 

// a base class

class A { };

// a derived class

class B : A { };

 

int main()

{

        char c;

        float f;

        

        // using typeinfo operator, == for comparison

        if (typeid(c) == typeid(f))

              cout<<"c and f are the same type."<<endl;

        else

              cout<<"c and f are different type."<<endl;       

        // using true and false comparison...

        // name() and before() are typeinfo member functions...

        cout<<typeid(int).name();

        cout<<" before "<<typeid(double).name()<<": "<<

        (typeid(int).before(typeid(double)) ? T:F)<<endl;       

        cout<<typeid(double).name();

        cout<<" before "<<typeid(int).name()<<": "<<

        (typeid(double).before(typeid(int)) ? T:F)<<endl;      

        cout<<typeid(A).name();

        cout<<" before "<<typeid(B).name()<<": "<<

        (typeid(A).before(typeid(B)) ? T:F)<<endl;

        return 0;

}

 

Output:

 

C++ Typecasting inheritance rtti program example

// getting the run time type information...

#include <iostream>

#include <typeinfo>

using namespace std;

 

// polymorphic base class...

class __rtti Test

{

       // this makes Test a polymorphic class type.

       virtual void func() { };

};

// a derived class...

class Derived : public Test { };

 

int main(void)

{

       // instantiate Derived type object...

       Derived DerivedObj;

       // declare a Derived type pointer

       Derived *DerivedPtr;

       // initialize the pointer

       DerivedPtr = &DerivedObj;

      

       // do the run time checking...

       if(typeid(*DerivedPtr) == typeid(Derived))

       // check the type of *DerivedPtr

       cout<<"Ptr *DerivedPtr type name is "<<typeid(*DerivedPtr).name();

       if(typeid(*DerivedPtr) != typeid(Test))

       cout<<"\nPointer DerivedPtr is not a Test class type.\n";

       return 0;

}

 

Output:

 

C++ Typecasting inheritance rtti run time type information

// run time type information...

#include <iostream>

#include <typeinfo>

using namespace std;

 

class Base

{

       public:

           virtual void funct(){ }

};

class Derived:public Base{ };

 

int main()

{

       Derived* Test1 = new Derived;

       Base* Test2 = Test1;

      

       cout<<"The type name of Test1 is: ";

       cout<<typeid(Test1).name()<<endl;

       cout<<"The type name of *Test1 is: ";

       cout<<typeid(*Test1).name()<<endl;

       cout<<"The type name of Test2 is: ";

       cout<<typeid(Test2).name()<<endl;

       cout<<"The type name of *Test2 is: ";

       cout<<typeid(*Test2).name()<<endl;

       delete Test1;

       return 0;

}

 

Output:

 

C++ Typecasting inheritance rtti run time type information

 

22.6  reinterpret_cast

// using reinterpret_cast, int to

// unsigned int pointers conversion

#include <iostream>

using namespace std;

 

unsigned int* Test(int *q)

{

       // convert int pointer to unsigned int pointer

       unsigned int* code = reinterpret_cast<unsigned int*>(q);

       // return the converted type data, a pointer...

       return code;

}

 

int main(void)

{

       // array name is a pointer...

       int a[10];

 

       cout<<"int pointer           unsigned int pointer"<<endl;

       for(int i = 0;i<=10;i++)

              cout<<(a+i)<<" converted to "<<Test(a+i)<<endl;

       return 0;

}

 

Output:

 

C++ Typecasting inheritance reinterpret_cast example

 

2.2.7 explicit Keyword

// a simple class, compiled using visual C++ .Net

#include  <iostream>

using namespace std;

 

class  MyStack

{

public:

// create a stack with initial size

MyStack(int initsize);

~MyStack(void);

};

MyStack::MyStack(int initsize)

{

static x;

cout<<"Constructor: Pass #"<<x<<endl;

x++;

}

MyStack::~MyStack(void)

{

static y;

cout<<"Destructor: Pass #"<<y<<endl;

y++;

}

 

// the main program

int main()

{

// the initial stack size is 10

MyStack p(20);

 

// but, there will be new stack objects with size of 30!

p = 30;

cout<<"Without the explicit keyword!\n";

return 0;

}

 

Output:

 

C++ Typecasting inheritance explicit keyword

p = 30;

// a simple class, compiled using visual C++ .Net

#include  <iostream>

using namespace std;

 

class  MyStack

{

public:

// create a stack with initial size

explicit MyStack(int initsize);

~MyStack(void);

};

// constructor

MyStack::MyStack(int initsize)

{

static x;

cout<<"Constructor: Pass #"<<x<<endl;

x++;

}

// destructor

MyStack::~MyStack(void)

{

static y;

cout<<"Destructor: Pass #"<<y<<endl;

y++;

}

 

// the main program

int main()

{

// the initial stack size is 10

MyStack p(20);

// but, there will be new stack objects with size of 30!

// p = 30;

cout<<"With the explicit keyword!\n";

return 0;

}

 

Output:

 

MyStack p1(30);    // OK

MyStack p2 = 30;  // error

// run time type information, compiled using VC++/VC++ .Net

#include <iostream>

#include <typeinfo>

using namespace std;

 

class Base

{

     public:

         virtual void funct(){}

};

class Derived:public Base{};

 

int main()

{

     Derived* Test1 = new Derived;

     Base* Test2 = Test1;

 

     cout<<"The type name of Test1 is: ";

     cout<<typeid(Test1).name()<<endl;

     cout<<"The type name of *Test1 is: ";

     cout<<typeid(*Test1).name()<<endl;

     cout<<"The type name of Test2 is: ";

     cout<<typeid(Test2).name()<<endl;

     cout<<"The type name of *Test2 is: ";

     cout<<typeid(*Test2).name()<<endl;

     delete Test1;

     return 0;

}

 

Output:

 

C++ Typecasting using Visual C++

// **********-typecast.cpp-**********

// upcast conversion using dynamic_cast

#include <iostream>

using namespace std;

 

// base class

class Base1 { };

// derived class...

class Derived1:public Base1 { };

// another derived class

class Derived2:public Derived1{ };

// dynamic_cast test function...

void funct1()

{

      // instantiate an object.

      Derived2* Test1 = new Derived2;

     

      // upcasting, from derived class to base class,

      // Derived1 is a direct from Base1

      // making Test2 pointing to Derived1 sub-object of Test1

      Derived1* Test2 = dynamic_cast<Derived1*>(Test1);

      cout<<"Derived1* Test2 = dynamic_cast<Derived1*>(Test1);"<<endl;

      if(!Test2)

         cout<<"The conversion is fail..."<<endl;

      else

         cout<<"The conversion is successful..."<<endl;

      // upcasting, from derived class to base class

      // Derived2 is an indirect from Base1

      Base1* Test3 = dynamic_cast<Derived1*>(Test1);

      cout<<"\nBase1* Test3 = dynamic_cast<Derived1*>(Test1);"<<endl;

      if(!Test3)

        cout<<"The conversion is fail..."<<endl;

      else

        cout<<"The conversion is successful..."<<endl;

}

 

int main()

{

   funct1();

   return 0;

}

 

[bodo@bakawali ~]$ g++ typecast.cpp -o typecast

[bodo@bakawali ~]$ ./typecast

 

Derived1* Test2 = dynamic_cast<Derived1*>(Test1);

The conversion is successful...

 

Base1* Test3 = dynamic_cast<Derived1*>(Test1);

The conversion is successful...

 

tenouk fundamental of the C++ object oriented tutorial

 

 

 

 

 

 

 

 

 

 

 

Further typecasting related reading:

 

  1. Source code for the program examples are available in C/C++ Typecasting source codes.

  2. Check the best selling C / C++, Object Oriented and pattern analysis books at Amazon.com.

 

 

 

 

 

 

|< C++ Typecasting 1 | Main | Namespaces >| Site Index | Download |


C++ Typecasting:  Part 1 | Part 2