Type Conversion
Type Coercion
  1. chars, shorts, and unsigned shorts are automatically promoted to int
  2. When an operator works with two values of different data type, the lower ranking value is promoted to the type of the higher ranking value
  3. When the final value of an expression is assigned to a variable, it will be converted to the data type of that variable
  4. If a negative integer value is converted to an unsigned type, the resulting value corresponds to its 2's complement bitwise representation
  5. The conversions from/to bool consider false equivalent to zero; true is equivalent to all other values and is converted to the equivalent of 1
  6. If the conversion is from a floating-point type to an integer type, the value is truncated (the decimal part is removed). If the result lies outside the range of representable values by the type, the conversion causes undefined behavior
  7. Otherwise, if the conversion is between numeric types of the same kind (integer-to-integer or floating-to-floating), the conversion is valid, but the value is implementation-specific (and may not be portable).
Implicit Conversion
#include <iostream>
#include <typeinfo>

int main(int argc, char *argv[])
{
	//char
	char c = 'a';
	std::cout<<typeid(c+1).name()[0]<<std::endl;

	//float and integer
	float a = 10.5;
	int b = 10;
	std::cout<<typeid(a+b).name()[0]<<std::endl;

	//negative integer to unsigned integer
	unsigned int d = -1;
	std::cout<<d<<std::endl;

	//bool to integer
	bool e = true, f = false;
	std::cout<<"True: "<<e<<" False: "<<f<<std::endl;

	//integer to bool
	std::cout<<std::boolalpha<<"1: "<<bool(1)<<" 0: "<<bool(0)<<" -1: "<<bool(-1)<<std::endl;
	std::cout<<std::noboolalpha;

	//float to integer
	float g = 3.14;
	int h = g;
	std::cout<<"Float to Int: "<<h<<std::endl;

	return 0;
}
			
Implicit Conversion with Classes
// implicit conversion of classes:
#include <iostream>

class A {};

class B {
public:
  // conversion from A (constructor):
  B (const A& x) {
	  std::cout<<"Constructor ..."<<std::endl;
  }
  // conversion from A (assignment):
  B& operator= (const A& x) {
	  std::cout<<"Assignment ..."<<std::endl;
	  return *this;
  }
  // conversion to A (type-cast operator)
  operator A() {
	  std::cout<<"Type-cast Operator ..."<<std::endl;
	  return A();
  }
};

int main ()
{
  A foo;
  B bar = foo;    // calls constructor
  bar = foo;      // calls assignment
  foo = bar;      // calls type-cast operator
  return 0;
}
			
Explicit
//Vehicle.h
#ifndef VEHICLE_H
#define VEHICLE_H
#include <iostream>
#include <string>

class Vehicle
{
	private:
		std::string producer;
	public:
		//constructor
		Vehicle(std::string s);

		std::string getProducer() const {return producer;}
		void setProducer(std::string producer);

		std::string toString();

		~Vehicle();
};
#endif
			
//Vehicle.cpp
#include <iostream>
#include <string>
#include "Vehicle.h"

//constructor
Vehicle::Vehicle(std::string s):producer(s)
{
	std::cout<<"Vehicle Constructor ..."<<std::endl;
}

void Vehicle::setProducer(std::string producer)
{
	this->producer = producer;
}

std::string Vehicle::toString()
{
	std::string temp;
	temp = "Vehicle Producer: "+producer;
	return temp;
}

Vehicle::~Vehicle()
{
	std::cout<<"Vehicle Destructor ..."<<std::endl;
}
			
//main.cpp
#include <iostream>
#include <string>
#include "Vehicle.h"

void display(Vehicle v)
{
	std::cout<<v.toString()<<std::endl;
}

int main(int argc, char *argv[])
{
	Vehicle v("Buick");
	display(v);

	std::string temp = "Honda";
	display(temp);//due to implicit conversion, string will converted to Vehicle automatically

	return 0;
}
			
#ifndef VEHICLE_H
#define VEHICLE_H
#include <iostream>
#include <string>

class Vehicle
{
	private:
		std::string producer;
	public:
		//constructor
		explicit Vehicle(std::string s);

		std::string getProducer() const {return producer;}
		void setProducer(std::string producer);

		std::string toString();

		~Vehicle();
};
#endif
		
Type Cast of Built-int Data Types
#include <iostream>

int main(int argc, char *argv[])
{
	double x = 3.14;
	int temp;

	temp = int(x);//C++ Style 
	temp = (int) x;//C Style

	return 0;
}
			
const_cast
#include <iostream>

void display(int *number)
{
	std::cout<<*number<<std::endl;
}

int main(int argc, char *argv[])
{
	int i = 10;
	const int *a = &i;

	display(const_cast<int *>(a));

	return 0;
}
			
dynamic_cast
//Vehicle.h
#ifndef VEHICLE_H
#define VEHICLE_H
#include <iostream>
#include <string>

class Vehicle
{
	private:
		std::string producer;
	public:
		//constructor
		Vehicle() {}
		Vehicle(std::string s);

		std::string getProducer() const {return producer;}
		void setProducer(std::string producer);

		virtual std::string toString();

		virtual ~Vehicle();
};
#endif

//Vehicle.cpp
#include <iostream>
#include <string>
#include "Vehicle.h"

//constructor
Vehicle::Vehicle(std::string s):producer(s)
{
	std::cout<<"Vehicle Constructor ..."<<std::endl;
}

void Vehicle::setProducer(std::string producer)
{
	this->producer = producer;
}

std::string Vehicle::toString()
{
	std::string temp;
	temp = "Vehicle Producer: "+producer;
	return temp;
}

Vehicle::~Vehicle()
{
	std::cout<<"Vehicle Destructor ..."<<std::endl;
}

//Car.h
#ifndef CAR_H
#define CAR_H
#include <iostream>
#include <string>
#include "Vehicle.h"

class Car : public Vehicle
{
	private:
		std::string model;
	public:
		//constructor
		Car() {};
		Car(std::string p, std::string m);

		std::string getModel() const {return model;}
		void setModel(std::string model);

		std::string toString();

		~Car();
};
#endif

//Car.h
#include <iostream>
#include <string>
#include "Vehicle.h"
#include "Car.h"

//constructor
Car::Car(std::string p, std::string m):Vehicle(p), model(m)
{
	std::cout<<"Car Constructor ..."<<std::endl;
}

void Car::setModel(std::string model)
{
	this->model = model;
}

std::string Car::toString()
{
	std::string temp;
	temp = "Car Producer: "+getProducer()+" Model: "+model;
	return temp;
}

Car::~Car()
{
	std::cout<<"Car Destructor ..."<<std::endl;
}

//main.cpp
#include <iostream>
#include <exception>
#include "Vehicle.h"
#include "Car.h"

int main(int argc, char *argv[])
{
	std::exception ep;

	Vehicle *v;
	Car *c = new Car("Honda", "Accord");
	
	//upcast
	//Convert Car to Vehicle
	std::cout<<"Upcast, Car to Vehicle ..."<<std::endl;
	try
	{
		v = dynamic_cast<Vehicle *>(c);
		std::cout<<v->toString()<<std::endl;
	} catch (std::exception & e)
	{
		std::cout<<"Upcast Error: "<<e.what()<<std::endl;
	}

	delete v;
	//delete c;

	//downcast
	Vehicle *v2 = new Vehicle("Buick");
	Vehicle *v3 = new Car("Buick", "Rendezvous");
	Car *c2;

	//Convert Car to Car
	std::cout<<"Downcast, Car to Car ..."<<std::endl;
	try
	{
		c2 = dynamic_cast<Car*>(v3);
		std::cout<<c2->toString()<<std::endl;
	} catch (std::exception &e)
	{
		std::cout<<"Downcast Error, Car to Car: "<<e.what()<<std::endl;
	}

	//Convert Vehicle to Car
	std::cout<<"Downcast, Vehicle to Car ..."<<std::endl;
	try
	{
		c2 = dynamic_cast<Car*>(v2);
		if (c2 == nullptr)
			throw ep;
		std::cout<<c2->toString()<<std::endl;
	} catch (std::exception &e)
	{
		std::cout<<"Downcast Error, Vehicle to Car: "<<e.what()<<std::endl;
	}

	delete v2;
	delete v3;

	return 0;
}
			
// bad_cast example
#include <iostream>       // std::cout
#include <typeinfo>       // std::bad_cast

class Base {virtual void member(){}};
class Derived : Base {};

int main () {
  try
  {
    Base b;
    Derived& rd = dynamic_cast<Derived&>(b);
  }
  catch (std::bad_cast& bc)
  {
     std::cerr << "bad_cast caught: " << bc.what() << '\n';
  }
  return 0;
}
		
static_cast
#include <iostream>
#include <exception>
#include "Vehicle.h"
#include "Car.h"

int main(int argc, char *argv[])
{
	std::exception ep;

	Vehicle *v;
	Car *c = new Car("Honda", "Accord");
	
	//upcast
	//Convert Car to Vehicle
	std::cout<<"Upcast, Car to Vehicle ..."<<std::endl;
	try
	{
		v = static_cast<Vehicle *>(c);
		std::cout<<v->toString()<<std::endl;
	} catch (std::exception & e)
	{
		std::cout<<"Upcast Error: "<<e.what()<<std::endl;
	}

	delete v;
	//delete c;

	//downcast
	Vehicle *v2 = new Vehicle("Buick");
	Vehicle *v3 = new Car("Buick", "Rendezvous");
	Car *c2;

	//Convert Car to Car
	std::cout<<"Downcast, Car to Car ..."<<std::endl;
	try
	{
		c2 = static_cast<Car*>(v3);
		std::cout<<c2->toString()<<std::endl;
	} catch (std::exception &e)
	{
		std::cout<<"Downcast Error, Car to Car: "<<e.what()<<std::endl;
	}

	//Convert Vehicle to Car
	std::cout<<"Downcast, Vehicle to Car ..."<<std::endl;
	try
	{
		c2 = static_cast<Car*>(v2);
		if (c2 == nullptr)
			throw ep;
		std::cout<<c2->toString()<<std::endl;
	} catch (std::exception &e)
	{
		std::cout<<"Downcast Error, Vehicle to Car: "<<e.what()<<std::endl;
	}

	delete v2;
	delete v3;

	return 0;
}
			
#include <iostream>

int main(int argc, char *argv[])
{
	//convert integer to float
	float temp = static_cast<float>(9)/5;
	std::cout<<temp<<std::endl;

	//convert integer to enum
	enum season {spring, summer, autumn, winter};
	season s = static_cast<season>(3);

	//convert *void to any pointer type
	char *a;
	unsigned char *b;

	//b = static_cast<unsigned char *>(a);//error
	b = static_cast<unsigned char *>(static_cast<void*>(a));
	//b = reinterpret_cast<unsigned char *>(a);

	return 0;
}
		
reinterpret_cast
#include <iostream>
#include "Vehicle.h"
#include "Car.h"

int main(int argc, char *argv[])
{
	//convert *void to any pointer type
	char *a = new char();
	a[0] = 'A';
	unsigned char *b;

	b = reinterpret_cast<unsigned char *>(a);
	std::cout<<b<<std::endl;

	delete a;

	//convert Car to Car
	Vehicle *v = new Car("Honda", "Accord");
	Car *c;

	c = reinterpret_cast<Car *>(v);

	std::cout<<c->toString()<<std::endl;

	delete v;

	//convert Vehicle to Car
	Vehicle *v2 = new Vehicle("Buick");
	Car *c2;

	c2 = reinterpret_cast<Car *>(v2);
	std::cout<<c2->toString()<<std::endl;

	delete v2;

	return 0;
}