20170608_请说出C++的四种强制类型转换的区别与联系
剑指offer——P22
1、C++中的四种强制类型转换分别是reinterpret_cast、const_cast、static_cast和dynamic_cast。
2、对于reinterpret_cast,它的功能基本上等同于C 语言中的显示强制类型转换符——小括号(),主要是将数据从一种类型转换为另一种类型,通常为操作数的位模式提供较低层的重新解释,也就是说将数据以二进制的形式进行重新解释。比如:
int i;
float f=3.1416;
i=reinterpret_cast<int>(f);
或者
int *ip;
char *cp="example";
ip=reinterpret_cast<int *>(cp);
此时,i的值为3。
此时,ip与cp的值完全相同。reinterpret_cast的作用是说将指针cp的值以二进制(位模式)的方式被解释为整型指针,并赋给ip。
3、对于const_cast,它是用来修改操作数的const属性的,这个操作数必须要是常量,比如,常量指针被转换为非常量指针,并且仍然指向原来的对象;常量引用被转换为非常量引用,并且仍然指向原来的对象;常量对象被转换为非常量对象,否则,用const_cast来转换其他任何非常量类型都会引起编译错误。比如:
const double value=1.1;
double *dptr=NULL;
dptr=const_cast<double *>(&value);
此时,dptr就指向了value变量。4、对于static_cast,编译器隐式执行的任何类型转换都可以由static_cast显示来完成。比如:
double value=1.12;
int i;
i=value;
或者具有同样功能的下式:
i=static_cast<int>(value);
此时,i的值是1。注意,仅仅当类型之间可以进行隐式转换的时候,static_cast的转换才是合法的,否则将会出错。其中,类层次之间的下行转换除外,也就是说类层次间的下行转换是不能通过隐式转换完成的,但是它可以使用static_cast转换。
class base{};
class child:public base{};
base *b;
child *c;
c=b;//编译错误!
c=static_cast<child *>(b);//下行转换,正确!
但是,下行转换是指将基类指针或基类引用转换为派生类指针或派生类引用,由于没有动态类型检查,所以是不安全的。5、对于dynamic_cast<type>(expression),它是将操作数expression转换为type类型的对象,其中,type必须是类的指针、类的引用或是void*类型。如果type是指针类型,那么expression也必须是一个指针;如果type是一个引用,那么expression也必须是一个引用。
(1)与其他强制类型转换不同,dynamic_cast运算符涉及运行时类型检查。
- 运行时类型检查需要运行时信息,而这个信息存储在类的虚函数表vtbl中,只有定义了虚函数的类才有虚函数表,没有定义虚函数的类是没有虚函数表的,没有虚函数表的类如果使用dynamic_cast转换会导致编译错误。
(2)dynamic_cast主要用于类层次之间的上行转换和下行转换,还可以用于类之间的交叉转换。
-
在类层次之间进行上行转换时,dynamic_cast和static_cast的效果是一样的;
-
在类层次之间进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。也即,如果downcast是安全的(也就说,如果基类指针或者基类引用确实指向一个派生类对象),这个运算符会传回适当转型过的指针;如果downcast不安全(也就是说,基类指针或者基类引用没有指向一个派生类对象),这个运算符会传回空指针void*。