Casting examples in C++ Linux


#include <QCoreApplication>
#include <iostream>
using namespace std;
class A
{
};
class B
{
};
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    cout<<"Hello"<<endl;

    A *aa = new A;

//    B *bb = static_cast<B*>(aa);//Invalid cast A* to B*
//    B *bb = const_cast<B*>(aa);//Invalid cast A* to B*
//    B *bb = dynamic_cast<B*>(aa);//Invalid cast A* to B* source is not polymorphic
      B *bb = reinterpret_cast<B*>(aa);//OK
    return a.exec();
}
//---------------------------
#include <QCoreApplication>
#include <iostream>
using namespace std;
class A
{
public:
    virtual ~A(){}//making source A as polymorphic
};
class B
{

};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    cout<<"Hello"<<endl;

    A *aa = new A;

//    B *bb = static_cast<B*>(aa);//Invalid cast A* to B*
//    B *bb = const_cast<B*>(aa);//Invalid cast A* to B*
      B *bb1 = dynamic_cast<B*>(aa);//Compiles ok but run time crash
      B *bb2 = reinterpret_cast<B*>(aa);//OK
    return a.exec();
}
//-----------------------------------------
#include <QCoreApplication>
#include <iostream>
using namespace std;
class A
{
};
class B:public A
{
};
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    cout<<"Hello"<<endl;
    A *aa = new A;
    B *bb1 = static_cast<B*>(aa);//Ok
    //B *bb2 = const_cast<B*>(aa);//Invalid cast A* to B*
    //B *bb3 = dynamic_cast<B*>(aa);//Invalid cast A* to B*
    B *bb4 = reinterpret_cast<B*>(aa);//OK
    return a.exec();
}

//-----------------------------------------
#include <QCoreApplication>
#include <iostream>
using namespace std;
class A
{
public:
    virtual ~A(){}
};
class B:public A
{
};
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    cout<<"Hello"<<endl;
    A *aa = new A;
    B *bb1 = static_cast<B*>(aa);//Ok
    //B *bb2 = const_cast<B*>(aa);//Invalid cast A* to B*
    B *bb3 = dynamic_cast<B*>(aa);//ok
    B *bb4 = reinterpret_cast<B*>(aa);//OK
    return a.exec();
}
//Dynamic Cast demos
Dynamic_cast is used for down casting  polymorphic base pointer to derived class poinetr to access member function defined by derived class in safe way.
#include <iostream>
#include <exception>
using namespace std;
class base { virtual void dummy() {} };
class derived: public base { int a; };
int main ()
 {
      try
            {
                base * pba = new derived;
                base * pbb = new base;
                derived * pd;
                pd = dynamic_cast<derived*>(pba);//d to b dynamic_cast ok
                              //because polymorphic base class elese run time error
                if (pd == 0)
                    cout << "Null pointer on first type-cast" << endl;
                pd = dynamic_cast<derived*>(pbb);
                if (pd == 0)
                    cout << "Null pointer on second type-cast" << endl;//gets printed
            }
            catch (exception& e)
            {
                cout << "Exception: " << e.what();
            }
            return 0;
        }
      
      #include <iostream>
        #include <typeinfo>
        using namespace std;
        int main ()
        {
            int * a;
            int b;
            a = 0; b = 0;
            if (typeid(a) != typeid(b))
            {
                cout << typeid(a).name()<<endl;//pi
                cout << typeid(b).name()<<endl;//i
            }
            return 0;
        }
Example Code:
        #include <iostream>
        #include <typeinfo>
        #include <exception>
        using namespace std;
        class base
        {
            virtual void f(){}
        };
        class derived : public base {};
        int main ()
        {
            try
            {
                base* a = new base;
                base* b = new derived;
                cout << typeid(*a).name() << '\n';//4base
                cout << typeid(*b).name()<<"\n";//7derived
            }
            catch (exception& e)
            {
                cout << "Exception: " << e.what() << endl;
            }
            return 0;
        }
Example Code:
        #include <typeinfo>
        #include <iostream>
        using namespace std;
        class A
        {
            public:
            virtual ~A();
        };
        int main()
        {
            A* a = NULL;
            try
            {
                cout << typeid(*a).name() << endl;
            }
            catch (bad_typeid)
            {
                cout << "Object is NULL" << endl;
            }
        }
Example Code:
        #include <iostream>
        using namespace std;
        struct A
        {
            virtual void f() 
            {
                cout << "Class A" << endl;
            }
        };
        struct B : A
        {
            virtual void f()
            {
                cout << "Class B" << endl;
            }
        };
        struct C : A
        {
            virtual void f()
            {
                cout << "Class C" << endl;
            }
        };
        void f(A* arg)
        {
            B* bp = dynamic_cast<B*>(arg);
            C* cp = dynamic_cast<C*>(arg);
            if (bp)
                bp -> f();
            else if (cp)
                cp -> f();
            else
                arg -> f(); 
        };
        int main()
        {
            A aobj;
            C cobj;
            A* ap = &cobj;
            A* ap2 = &aobj;
            f(ap);
            f(ap2);
        }
/*
class C
Class A
*/
Example Code:
#include<iostream>
using namespace std;
class Base
{
public:
virtual    void f(){cout<<"Base::f"<<endl;}
};
class Derive:public Base
{
public:
virtual     void f(){cout<<"Derived::f"<<endl;}
};
int main()
{
//CASE 1----------------------------------------------------------------
//Base *b = new Derive();
Base *pb;
Derive *pd;
//pb=pd;//No error
//pd=pb;error: invalid conversion from ‘Base*’ to ‘Derive*’

pb = dynamic_cast<Base*>(pd);
if(pd!=NULL)
{
cout<<"derive to base pass\n";
//pd->f();//run time crash
//pb->f();// run time rash
}
else if(pd==NULL)
{
cout<<"derive to base fail\n";
}
Base *b = new Derive();
Base *pb2;
Derive *pd2;
//pb2=pd2;//No error
//pd2=pb2;//error: invalid conversion from ‘Base*’ to ‘Derive*’

//CASE 2------------------------------------------------------------------
b = dynamic_cast<Base*>(pd2);
if(pd2!=NULL)
{
cout<<"derive to base pass2\n";
//pd2->f();//run time crash
//pb2->f();// run time rash
}
else if(pd2==NULL)
{
cout<<"derive to base fail2\n";
}
//CASE 3---------------------------------------------------------------
//Base *b = new Derive();
cout<<"31"<<endl;
Base *pb3;
cout<<"32"<<endl;
Derive *pd3;
cout<<"33"<<endl;
//pb=pd;//No error
//pd=pb;error: invalid conversion from ‘Base*’ to ‘Derive*’
/*
pd3 = dynamic_cast<Derive*>(pb3);//BOOOOM
cout<<"34"<<endl;
if(pb3!=NULL)
{
cout<<"base to derive pass 3\n";
}
else if(pb3==NULL)
{
cout<<"base to derive 3\n";
}
*/
//CASE 4-------------------------------------------------------------------
Base *b4 = new Derive();
//Base *pb4;
Derive *pd4;
pd4 = dynamic_cast<Derive*>(b4);//BOOM
cout<<"44"<<endl;
//if(pb4!=NULL)
//{
//cout<<"pb4 base to derive pass4\n";
//}
//else if(pb4==NULL)
//{
//cout<<"pb4 base to derive fail4\n";
//}

if(b4!=NULL)
{
cout<<"b4 base to derive pass4\n";
b4->f();//Derive::f
}
else if(b4==NULL)
{
cout<<"b4 base to derive fail4\n";
}
if(pd4!=NULL)
{
cout<<"pd4 base to derive pass4\n";
pd4->f();//Derive::f()
}
else if(pd4==NULL)
{
cout<<"pd4 base to derive fail4\n";
}
return 0;
}
Example Code:
#include<iostream>
using namespace std;
class Base
{
public:
    virtual void f(){cout<<"Base::f"<<endl;}
};
class Derive:public Base
{
public:
    virtual void f(){cout<<"iDerived::f"<<endl;}
};
int main()
{
Base *b = new Derived;
return 0;
}

        #include <iostream>
        using namespace std;
        struct A
        {
            virtual void f() 
            {
                cout << "Class A" << endl;
            }
        };
        struct B : A
        {
            virtual void f()
            {
                cout << "Class B" << endl;
            }
        };
        struct C : A
        {
            virtual void f()
            {
                cout << "Class C" << endl;
            }
        };
        void f(A* arg)//cobj the aobj
        {
            B* bp = dynamic_cast<B*>(arg);//cobj to bobj fails //arg2. aobj to bobj fails
            C* cp = dynamic_cast<C*>(arg);//cobj to cobj pass //arg2.  aobj to cobj fails

            if (bp)
        {
        cout<<"bp\n";
                bp -> f();
        }
            else if (cp)
        {
        cout<<"cp\n";
                cp -> f();
        }
            else
        {
        cout<<"else\n";
                arg -> f(); 
        }
        };
        int main()
        {
            A aobj;
            C cobj;
            A* ap = &cobj;
            f(ap); //Cp C

            A* ap2 = &aobj;
            f(ap2);//else A

        }
 

1 comment:

  1. static_cast is the first cast you should attempt to use. It does things like implicit conversions between types (such as int to float, or pointer to void*), and it can also call explicit conversion functions (or implicit ones). In many cases, explicitly stating static_cast isn't necessary, but it's important to note that the T(something) syntax is equivalent to (T)somethingand should be avoided (more on that later). A T(something, something_else) is safe, however, and guaranteed to call the constructor.
    static_cast can also cast through inheritance hierarchies. It is unnecessary when casting upwards (towards a base class), but when casting downwards it can be used as long as it doesn't cast through virtual inheritance. It does not do checking, however, and it is undefined behavior to static_cast down a hierarchy to a type that isn't actually the type of the object.
    const_cast can be used to remove or add const to a variable; no other C++ cast is capable of removing it (not even reinterpret_cast). It is important to note that modifying a formerly constvalue is only undefined if the original variable is const; if you use it to take the const off a reference to something that wasn't declared with const, it is safe. This can be useful when overloading member functions based on const, for instance. It can also be used to add const to an object, such as to call a member function overload.
    const_cast also works similarly on volatile, though that's less common.



    dynamic_cast is almost exclusively used for handling polymorphism. You can cast a pointer or reference to any polymorphic type to any other class type (a polymorphic type has at least one virtual function, declared or inherited). You can use it for more than just casting downwards -- you can cast sideways or even up another chain. The dynamic_cast will seek out the desired object and return it if possible. If it can't, it will return nullptr in the case of a pointer, or throw std::bad_cast in the case of a reference.
    dynamic_cast has some limitations, though. It doesn't work if there are multiple objects of the same type in the inheritance hierarchy (the so-called 'dreaded diamond') and you aren't using virtual inheritance. It also can only go through public inheritance - it will always fail to travel through protected or private inheritance. This is rarely an issue, however, as such forms of inheritance are rare.

    reinterpret_cast is the most dangerous cast, and should be used very sparingly. It turns one type directly into another - such as casting the value from one pointer to another, or storing a pointer in an int, or all sorts of other nasty things. Largely, the only guarantee you get with reinterpret_cast is that normally if you cast the result back to the original type, you will get the exact same value (but not if the intermediate type is smaller than the original type). There are a number of conversions that reinterpret_cast cannot do, too. It's used primarily for particularly weird conversions and bit manipulations, like turning a raw data stream into actual data, or storing data in the low bits of an aligned pointer.

    ReplyDelete