这里有两篇文章写的很好,还举了例子
http://www.cnblogs.com/jerry19880126/archive/2012/08/14/2638192.html
http://www.cnblogs.com/goodhacker/archive/2011/07/20/2111996.html
一、什么是类型转换
通过改变一个变量的类型为别的类型,进而改变该变量的表示方式,这就是类型转换
二、传统的C风格转换
例如
int i;
double d;
i = (int)d;
或者
i = int(d);
有的时候用c风格的转换是不合适的,因为它可以在任意类型之间转换,
比如你可以把一个指向const对象的指针转换成指向非const对象的指针,
把一个指向基类对象的指针转换成指向一个派生类对象的指针,
这两种转换之间的差别是巨大的,但是传统的c语言风格的类型转换没有区分这些。
还有一个缺点就是,c风格的转换不容易查找,他由一个括号加上一个标识符组成,
而这样的东西在c++程序里一大堆。所以c++为了克服这些缺点,引进了4新的类型转换操作符。
三、四种新的类型转换符
reinpreter_cast<type-id> (expression)
static_cast<type-id> (expression)
dynamic_cast<type-id> (expression)
const_cast<type-id> (expression)
1)reinterpret_cast:仅仅重新解释类型,但没有进行二进制的转换。
reinterpret_cast转换一个指针为其他类型的指针,也允许一个指针转换为整型,反之亦然
reinterpret_cast能够在不相关的类型之间转换,比如int指针转为char指针。
操作结果只是简单地从一个指针到别的指针的值的二进制拷贝。
在类型之间指向的内容不做任何类型的检查和转换。
reinterpret_cast就像传统的类型转换一样对待所有指针的类型转换
class A{};
class B{};
A *a = new A;
B *b = reinterpret_cast<B*>(a);
2)static_cast:命名上理解是静态类型转换,如int转换成char。
static_cast允许执行任意的隐式转换和相反转换动作
可以被用于强制隐型转换(例如,non-const 对象转型为 const 对象,int 转型为 double,等等)
还可以用于很多这样的转换的反向转换(例如,void* 指针转型为有类型指针,基类指针转型为派生类指针)
但是它不能将一个 const 对象转型为 non-const 对象(只有 const_cast 能做到),它是最接近于C-style的转换
1)用于基本数据类型之间的转换,如把int转换成char,non-const 对象转型为 const 对象(这里相反方向不可以,C++只有const_cast可以)。
2)把空指针转换成目标类型的指针。(之前的做法是用强制转换(type-id*))
3)把任何类型的表达式转换成void类型。
4)应用到类的指针上,
它允许子类类型的指针转换为父类类型的指针(这是有效的隐式转换);
同时,也允许父类类型的指针转换为它的子类类型的指针
class Base {};
class Derived : public Base {};
Base *a = new Base;
Derived *b = static_cast<Derived *>(a);
也可以用于执行类型定义的显式的转换,以及基础类型之间的标准转换。
double d = 3.1415926;
int i = static_cast<int>(d);
std::cout << i; // 3
3)dynamic_cast:命名上理解是动态类型转换,如子类和父类之间的多态类型转换。
dynamic_cast 主要用于执行“安全的向下转型”,不能用于内置的基本数据类型的强制转换。
其他三种都是编译时完成的,dynamic_cast是运行时处理的,运行时要进行类型检查。
dynamic_cast只用于对象的指针和引用。
当用于多态类型时,它允许任意的隐式类型转换以及相反过程。
不过,与static_cast不同,
在隐式转换的相反过程中,dynamic_cast会检查操作是否有效!
如果被转换的指针不是一个被请求的有效完整的对象指针(转换失败),返回NULL
在类层次间进行向上转换时,和dynamic_cast和static_cast是一样的
在用于继承体系中的向下转型,即将基类指针转换为派生类指针,比static_cast更严格更安全,但牺牲了效率
使用dynamic_cast进行转换时,基类中一定要有虚函数,否则编译不通过
class Base{
public:
virtual dummy(){}
};
class Derived:public Base{};
Base* b1 = new Derived;
Base* b2 = new Base;
Derived* d1 = dynamic_cast<Derived>(b1); //成功
Deriver* d2 = dynamic_cast<Derived>(b2); //失败,返回NULL
4)const_cast:字面上理解就是去const属性。
const_cast用于修改类型的const或volatile属性,或者是设置或者是移除。
其他三种操作符是不能修改一个对象的常量属性的
常量指针被转化成非常量指针,并且仍然指向原来的对象;
常量引用被转换成非常量引用,并且仍然指向原来的对象;
常量对象被转换成非常量对象。
const_cast只有const类型的变量才能使用。
比如,有时候有的函数的形参类型为非const类型,那么如果你要将一个const类型的参数传入就会报错。
所以在这种情况下需要先使用const_cast转化一下
class C {};
const C *a = new C;
C *b = const_cast<C *>(a);
使用
总结
去const属性用const_cast;
基本类型转换用static_cast;
多态类之间的类型转换用dynamic_cast;
不同类型的指针类型转换用reinterpret_cast;
四种类型转换操作符对于隐式的类型转换没有必要。