【本文链接】
http://www.cnblogs.com/hellogiser/p/static_cast-dynamic_cast-const_cast-reinterpret_cast.html
【分析】
旧式风格 vs C++风格
1
2 3 4 5 6 7 |
(new_type) expression // c-style
new_type (expression) // function-style dynamic_cast <new_type> (expression) |
【static_cast】
用于基本数据类型之间的转换,如把int转换成char,把int转换成enum,这种转换的安全性也要开发人员来保证。
1
2 3 4 5 6 7 8 |
// basic type cast
, B, C }; ; ; char c = static_cast<char>(ui); int i = static_cast<int>(d); int j = static_cast<int>(B); double k = static_cast<double>(ui); |
用于类层次结构中基类和子类之间指针或引用的转换。(非多态类型转换,没有virtual)
- 进行上行转换(把子类的指针或引用转换成基类表示)是安全的;
- 进行下行转换(把基类指针或引用转换成子类表示)时,转换是合法的,但是由于没有动态类型检查,所以是不安全的。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
/*
version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/9/22 */ #include "stdafx.h" class Base class Derived: public Base void test_static_cast() int main() |
【dynamic_cast 】
用法:dynamic_cast < type-id > ( expression )
该运算符把expression转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void *;
如果type-id是类指针类型,那么expression也必须是一个指针,如果type-id是一个引用,那么expression也必须是一个引用。
dynamic_cast主要用于具有Virtual函数类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。(多态类型转换,必须要有virtual)
- 在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;
- 在进行下行转换时,dynamic_cast具有类型检查的功能,并且要求基类具有virtual函数,比static_cast更安全。(如果指针能够不能够正确转换,返回NULL;如果引用不能正确转换,则抛出bad_cast异常)
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
/*
version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/9/22 */ #include "stdafx.h" class Base class Derived: public Base void test_static_cast() } void test_dynamic_cast() Derived *pd; pd = dynamic_cast<Derived *>(d); // pd !=null delete d; int main() |
上述例子,如果改为static_cast,则结果如下
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
/*
version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/9/22 */ #include "stdafx.h" class Base class Derived: public Base void test_static_cast() Derived *pd; pd = static_cast<Derived *>(d); // pd !=null delete d; int main() |
由此可以看出,对于将基类指针转换为派生类指针的下行转换:
- static_cast由于不做类型检查,能够正常转换,但是转换后的指针pb指向的是一个不完整的Derived对象,访问Derived对象的成员变量,会出现随机值(-33686019),而访问虚函数fun调用的也是Base的。
- dynamic_cast做类型检查,知道不能够正常转换,因此返回NULL。
【const_cast】
const_cast:用来消除const, volatile, __unaligned属性的转换。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
/*
version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/9/22 */ #include "stdafx.h" void print (char *str) void test_const_cast_fun () class CCTest void CCTest::setNumber( int num ) void CCTest::printNumber() const void test_const_cast_class() int main() /* |
【reinterpret_cast】
字面意思:重新解释(类型的比特位)。能够在任何类型的指针之间进行转换,也允许将任何整数类型转换为任何指针类型以及反向转换。在所有的转换中最“危险”,一定要慎用。
来看一个具体的例子:将变量地址转换为一个整数,再由整数转换为对应的指针。
【代码】
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
/*
version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/9/22 */ #include "stdafx.h" // address---> integer value /* int main() |
在实际中的应用价值:根据地址计算唯一的Hash值。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
/*
version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/9/22 */ #include "stdafx.h" // Returns a hash code based on an address void test_reinterpret_cast() int main() /* |
【参考】
http://www.cplusplus.com/doc/tutorial/typecasting/
http://blog.csdn.net/callmeback/article/details/4040583
http://www.cnblogs.com/goodcandle/archive/2009/03/17/1413907.html