Showing posts with label Cast. Show all posts
Showing posts with label Cast. Show all posts

Wednesday, 3 February 2010

reinterpret_cast in C++

From the Cpp Reference:

Syntax: TYPE reinterpret_cast (object);

The reinterpret_cast operator changes one data type into another. It should be used to cast between incompatible pointer types.

Suppose we have two variables, int a and char b

In C programming we can covert from b to a by:
a = (int)b;

In C++, the proper way to do this would be by using cast. One way is to use:
a = reinterpret_cast(b);

Most of the time reinterpret_cast is not required in the programs and can often be very dangerous. The following is from MSDN:

The reinterpret_cast operator also allows any integral type to be converted into any pointer type and vice versa. Misuse of the reinterpret_cast operator can easily be unsafe. Unless the desired conversion is inherently low-level, you should use one of the other cast operators.

The reinterpret_cast operator can be used for conversions such as char* to int*, or One_class* to Unrelated_class*, which are inherently unsafe.

The result of a reinterpret_cast cannot safely be used for anything other than being cast back to its original type. Other uses are, at best, nonportable.

The reinterpret_cast operator cannot cast away the const, volatile, or __unaligned attributes. See const_cast Operator for information on removing these attributes.

The reinterpret_cast operator converts a null pointer value to the null pointer value of the destination type.

One practical use of reinterpret_cast is in a hash function, which maps a value to an index in such a way that two distinct values rarely end up with the same index.

Instead of reinterpret_cast people generally prefer static_cast

Lets look at an example of reinterpret_cast:





//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>

using namespace
std;

int
main()
{

int
a = 22;
float
b = (float)33.3333;

cout<<"1. a = "<< a <<" b = "<< b <<endl;

a = (int)b; //Old C programming way
cout<<"2. a = "<< a <<" b = "<< b <<endl;

//Wont work in this case because floating point format is different
a = reinterpret_cast<int&>(b);
cout<<"3. a = "<< a <<" b = "<< b <<endl;

a = static_cast<int>(b); //Correct approach
cout<<"4. a = "<< a <<" b = "<< b <<endl;

char
c;
//Convert int to char
c = reinterpret_cast<char&>(a);
cout<<"5. c = "<< (int)c <<" a = "<< a <<endl;

//Dangerous to convert from char to int
a = reinterpret_cast<int&>(c);
cout<<"6. c = "<< (int)c <<" a = "<< a <<endl;

//What we actually wanted was just the last 8 bits so...
a = a & 0x000000FF; //00 = 8 bits
cout<<"7. c = "<< (int)c <<" a = "<< a <<endl;

return
0;
}






The output is as follows:

Wednesday, 16 December 2009

BOOL to bool

I faced a very simple problem the other day. The compiler started generating a warning:

warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)

The reason being that because I was including some Windows file that included windef.h. In windef.h, it says: typedef int BOOL;

What I was trying to do was to cast that BOOL to bool. Of course we can suppress the warning easily by the #pragma directives as discussed earlier but there has to be a better and a simpler way. Then it clicked, how about a simple != 0 comparison. Here is the sample code:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>
#include<windows.h>
#include<windef.h>

using namespace
std;

int
main()
{

BOOL someVal = 1;

bool
firstApproach = someVal; //Generates warning C4800
cout<<"firstApproach = "<<firstApproach<<endl;

bool
secondApproach = (someVal != 0); //No Warning
cout<<"secondApproach = "<<secondApproach<<endl;

return
0;
}

Wednesday, 9 December 2009

Catching the 'Divide By Zero' exceptions

I was surprised to find that C++ does not catch divide by 0 exceptions by default. The code will crash when a divide by 0 situation occurs. As a result the only option is to write our own class or method to handle divide by 0 scenario. The example below shows how to handle the Divide by zero scenario and how to construct an exception.







//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>

using namespace
std;

class
Division
{

public
:
double
quotient(int numerator, int denominator);
private
:

};


double
Division::quotient(int numerator, int denominator)
{

if
(!denominator)
{

exception e("Divide by 0 exception");
throw
(e);
}

return
(static_cast< double >( numerator ))/denominator;
}



int
main()
{

Division d;
try

{

cout<<"1. (100/10) = "<<d.quotient(100, 10)<<endl;
cout<<"2. (10/4) = "<<d.quotient(10, 4)<<endl;
cout<<"3. (10/0) = "<<d.quotient(10, 0)<<endl;
cout<<"4. (30/9) = "<<d.quotient(30, 9)<<endl;
}

catch
(exception& e)
{

cout<<"Exception caught with cause :"<<e.what()<<endl;
}

return
0;
}








The output is as follows:


You can read more on this topic here.

Friday, 4 September 2009

Changing objects in 'const member functions' via Mutable

We saw last time an example of 'Const Member Functions' (also known as 'Inspectors'). In contrast the member functions without the const suffix are known as 'non-const member functions' or 'mutators'.

Sometimes it may be necessary to modify a data member (variable or object in your class) in a const member function. There are two approaches to do that. One is to use the const_cast and the other to use 'mutable'. I use both the approaches in the example below:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//This example shows how to change objects in const member functions
#include<iostream>

using namespace
std;

class
ABC
{

public
:
int
func1(int a, int b);
int
func2(int a, int b) const;
private
:
int
x;
mutable
int y;
};


int
ABC::func1(int a, int b)
{

x = a, y = b;
cout<<"x = "<<x<<" and y = "<<y<<endl;
return
0;
}


int
ABC::func2(int a, int b) const
{

//x = a; - COMPILE ERROR because its const
int *temp = const_cast<int*>(&x); //Removing the const
*temp = a; //OK now
y = b; //OK because its defined as mutable
cout<<"x = "<<x<<" and y = "<<y<<endl;
return
0;
}


int
main()
{

ABC abc;
abc.func1(3, 7);
abc.func2(20, 40);
return
0;
}



The output is as follows:


Monday, 22 June 2009

An example of dynamic_cast

Lets look at an example of dynamic_cast where you can cast a pointer from Derived class to Base class. The example should be self explanatory:


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//A very simple program to explain dynamic cast

#include <iostream>

using namespace
std;

//Base class
class A
{

public
:
int
a;
int
b;
private
:
int
c;
};


//Derived class
class B :public A
{

private
:
int
d;
};


//function that prints a and b
void function(A a)
{

cout<<"\n a = "<<a.a<<" b = "<<a.b<<endl;
}


int
main()
{

A *a;
B *b=new(B);
b->a = 20, b->b = 40;
a = dynamic_cast<A*>(b); //Dynamic cast from Dervied to Base
function(*a);
return
0;
}



The output is as follows:

Monday, 27 April 2009

Using Const Cast

The following is an example to use the const_cast in C++.


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Example shows how to use const_cast
#include<iostream>

using namespace
std;

void
func1(int *x)
{

cout<<"\n2. xyz = "<<*x<<endl;

//Possible but its like cheating
(*x)++;
}



void
func2(const int *x)
{

cout<<"\n4. xyz = "<<*x<<endl;
//(*x)++; //Not possible to do this, compile time error
}

int
main()
{

int
xyz = 22;
const
int *abc = &xyz;
cout<<"\n1. xyz = "<<xyz<<endl;
//func1(abc); //Not possible to call, need a cast, compile time error
//Use const_cast only when you trust a function to not change the value
func1(const_cast<int *>(abc)); //Cast the constness of abc away
cout<<"\n3. xyz = "<<xyz<<endl;
func2(abc);
cout<<"\n5. xyz = "<<xyz<<endl;
}



The output of the program is as follows: