C++ type casting

Type casting means converting from one type of data into another type.  c++ language supports two types of conversion.    (1)Implicit conversion  or implicit casting (2) explicit conversion or explicit casting. A very simple example of typecasting is given below. the example is an implicit type conversion. In below example, the conversion of data from float to int is done implicitly, we don’t need to specify any type operators. we will discuss later in this article what are these type operators?

#include<iostream>
using namespace std;
int main()

{
	float a = 3.0;
	int b = a; // implicit casting float type into integer type
	return 0;
}

 

The C++ language supports four typecast operators: explicit type casting

  • static_cast
  • reinterpret_cast
  • const_cast
  • dynamic_cast

Explicit type casting is used  generally for user defined data type with the help of type conversion operators mentioned above. The data type like int, float,double etc are fundamental data type. user defined data type is supported by c++ and struct, enumeration and class are the example of user defined data types. Now let us discuss static_cast, reinterpret_cast, const_cast and dynamic_cast with examples and requirements for “when to use these operators.

static_cast:

static_cast operator is used when data types involved in conversion is known or certain. the one disadvantage is that it does not perform run time type check. the static_cast can be used for fundamental data type conversions like int to float, enums to int, short to int and it is called standard conversion like in below example.

#include<iostream>
using namespace std;
int main()

{
	int a = 20;
	int b = 3;
	double out;

	out = static_cast<double> (a) / b; // typecast a to double
	return 0;
}

static_cast can also be used to convert base class pointer to derived class pointer and vice-versa. but converting base class pointer into derived class pointer is not safe as derived class can have fields and methods that are not in base class.  see blow example code:

#include<iostream>
using namespace std;

class Base {
};

class Derived: public Base {
};

int main()

{

	Base *b;
	Derived *d;
	d = static_cast<Derived*> (b); // Not safe

	b = static_cast<Base*> (d); // safe
	return 0;
}

reinterpret_cast:

This cast operator is used to convert one type into fundamentally different type such as  char* to int* and one class type into unrelated class type.   it guarantees that if we cast a pointer to a different type, and then reinterpret_cast it back to the original type, we get the original value. for example.

int* a;
void* b = reinterpret_cast<void*>(a);
int* c = reinterpret_cast<int*>(b);

 

a and c contain the same value, but the value of b is unspecified.

const_cast:

const_cast is used to cast away (remove) const or volatile attribute of c++ variables. here is example to convert a const to non-const.

#include<iostream>

using namespace std;

int main()

{
const float x = 1.1;
float *ptr = const_cast<float*> (&x);
return 0;

}[/cpp]

Another example where we need to cast away the const attribute of cost object.

[cpp]
#include <iostream>
#include <stdlib.h>
using namespace std;
class Base
{
public:
void foo ()
{
cout<<"in Base"<<endl;
}
};
//const argument, cannot be modified...
void foo_1 (const Base &c)
{
Base &d = const_cast<Base&> (c); //here we need to cast away
// the constness of (const Base &)
d.foo();
}
int main ()
{
Base b;
foo_1(b);
return 0;
}[/cpp]
<h2><span style="text-decoration: underline;"><span style="color: #003366;"><strong>dynamic_cast:</strong></span></span></h2>
<span style="color: #333399;">Before going into details of dynamic_cast operator let us discuss some related topics involved in dynamic casting.</span>
<a href="http://wikistack.com/wp-content/uploads/2014/11/dyna.jpg"><img class="alignnone size-full wp-image-1513" src="http://wikistack.com/wp-content/uploads/2014/11/dyna.jpg" alt="dyna" width="400" height="249" /></a>
<ul>
 	<li><span style="text-decoration: underline;"><span style="color: #333399; text-decoration: underline;">upcasting</span></span></li>
</ul>
up-casting in c++ refers to convert  derived class pointer or reference to base class pointer or reference.

[cpp]#include<iostream>

class A{
};
class B:public A{
};
class C:public B{
};

int main()
{
A *a_obj;
B *b_obj;
C *c_obj;

a_obj = b_obj; //upcasting
b_obj = c_obj; //upcasting
return 0;
}[/cpp]
<ul>
 	<li><span style="color: #333399;">donwcasting</span></li>
</ul>
down casting refers to covert base class pointer or reference to derived class pointer or reference. try to compile blow sample code

[c]#include<iostream>

class A{
};
class B:public A{
};
class C:public B{
};

int main()
{
A *a_obj;
B *b_obj;
C *c_obj;

b_obj = a_obj; // downcasting
return 0;
}

The above code will not compile and give error:
error: invalid conversion from ‘A*’ to ‘B*’ [-fpermissive]
b_obj = a_obj; // downcasting

Why we are getting above error? we are getting above error because down casting in c++ is not allowed without explicit type cast.  now we have to do down casting like b_obj = (B *)a_obj; . this is explicit type casting.
So below modified code will compile successfully.

#include<iostream>
class A{
};
class B:public A{
};
class C:public B{
};

int main()
{
A *a_obj;
B *b_obj;
b_obj = (B *)a_obj; // downcasting explicitly
return 0;
}

Ok, above code will compile successfully but can you guess what is problem with this down casting. because we are assigning base class pointer to derived class then it is expectation from the code that base class object might have some derived class properties which is invalid. derived class object might have some extra function in it which is not present in base class object. it shows that down casting is not safe in this case. c++ provides dynamic_cast operator for safe down casting. Let us discuss How? Lets try to compile below code. will this code compile?

#include<iostream>

class A{
};
class B:public A{
};
class C:public B{
};

int main()
{
A *a_obj;
B *b_obj;
b_obj = dynamic_cast<B *>(a_obj); // downcasting
return 0;
}

The above code will not compile and give below error.

cannot dynamic_cast ‘a_obj’ (of type ‘class A*’) to type ‘class B*’ (source type is not polymorphic)
b_obj = dynamic_cast<B *>(a_obj); // downcasting

The above error is coming because dynamic_cast is only allowed if a class that is being down cast has at least one virtual method. virtual destructor is also allowed.

#include<iostream>

class A{
public:
A(){};
virtual ~A(){};
};
class B:public A{
};
class C:public B{
};
int main()
{
A *a_obj = new A();
B *b_obj = new B();
b_obj = dynamic_cast<B *>(a_obj); // downcasting
return 0;
}

dynamic_cast gives bad_cast exception in case of reference of an object in case of failure and in case of dynamic casting of pointer of an object if it fails the pointer is assigned null. this is run time checking.

Reference exception example:

#include<iostream>
#include<exception>
#include<typeinfo>

using namespace std;

class A{
public:
A(){};
virtual ~A(){};
};
class B:public A{
};
class C:public B{
};

int main()
{

A a_obj;

try{
B& b_obj = dynamic_cast<B&>(a_obj);
// cast will be successful only for B type objects.
}
catch(bad_cast& e)
{
cerr<<"bad cast caught: "<< e.what()<<endl;
}
return 0;
}

dynamic_cast with pointer example

#include <iostream>
using namespace std;

class A {
public:
A(){};
virtual ~A(){};
};

class B : A {
};

class C : A {
};

int main() {
A *aobj = new A();
C *cobj = new C();

// cast will be successful only for B type objects.
B* bp = dynamic_cast<B*>(aobj);
if( bp == NULL)
{
cout<<"dynamic cast fail for aobj\n";
}
C* cp = dynamic_cast<C*>(cobj);
if( cp == NULL)
{
cout<<"dynamic cast fail for cobj\n";
}

return 0;
}

 output:dynamic cast fail for aobj


Related Contents to follow