[C++] C++风格的强制类型转换探讨
2014-01-05 21:37
239 查看
C++风格的强制类型转换:const_cast,static_cast,dynamic_cast,reinterpret_cast。
使用:xxx_cast<type-id> (expression)
[b]const_cast[/b]
说明:该运算符用来修改类型的const或volatile属性。
[b]static_cast[/b]
说明:无条件强制转换,没有在运行时进行类型检查来保证转换的安全性,static_cast也不能去掉类型的const、volitale属性。
场景:
基类和子类之间转换:进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
用于基本数据类型之间的转换,如把int转换成char,把int转换成enum等。
把空指针转换成目标类型的空指针。
把任何类型的表达式转换成void类型。
[b]dynamic_cast[/b]
说明:type-id必须是类的指针、类的引用或者void*,运行时会进行类型安全检查(转换失败返回NULL)。
场景:
基类和子类之间转换,上行和下行转换都是安全的。
基类必须要有虚函数。
交叉转换(相同基类的不同子类之间的转换),但结果是NULL。
[b]reinterpret_cast[/b]
说明:仅仅重新解释类型,但没有做字节对齐。
场景:最普通的用途就是在函数指针类型之间进行转换,但是很难保证移植性。
结果:
static_cast转换之后结果 - reinterpret_cast转换之后的结果 = 4(即该测试类中的字节对齐长度)。
说明:static_cast在进行上行转换是安全的,static_cast计算了父子类指针转换的偏移量,并将之转换到正确的地址,而reinterpret_cast则不会做这层转换。
[b]总结[/b]
const_cast:去const或volatile属性时用到。
static_cast:基本类型转换(不包括指针类型)时用到。
daynamic_cast:基类与子类的指针(或引用)互相转换时用到。
reinterpret_cast:不同类型的指针类型转换(如:函数指针类型之间进行转换),慎用。
[b]参考[/b]
http://baike.baidu.com/view/1745221.htm
http://baike.baidu.com/view/1745207.htm
http://baike.baidu.com/view/1745213.htm
http://baike.baidu.com/view/1263731.htm
http://www.cnblogs.com/goodhacker/archive/2011/07/20/2111996.html
(完)
使用:xxx_cast<type-id> (expression)
[b]const_cast[/b]
说明:该运算符用来修改类型的const或volatile属性。
class TestA { public: TestA() { } public: int m_data; }; void foo() { const TestA ta; //ta1.m_data = 100; //编译错误 TestA *pTa = const_cast<TestA*>(&ta); pTa->m_data = 200; //OK TestA &taTmp = const_cast<TestA&>(ta); taTmp.m_data = 300; //OK } int main( int argc, char * argv[] ) { foo(); return 0; }
[b]static_cast[/b]
说明:无条件强制转换,没有在运行时进行类型检查来保证转换的安全性,static_cast也不能去掉类型的const、volitale属性。
场景:
基类和子类之间转换:进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
用于基本数据类型之间的转换,如把int转换成char,把int转换成enum等。
把空指针转换成目标类型的空指针。
把任何类型的表达式转换成void类型。
void foo() { int n = 6; char c = static_cast<char>(n); // 基本类型转换 double d = static_cast<double>(n); float f = static_cast<float>(n); int *pn = &n; //double *d = static_cast<double*>(&n) //无关类型指针转换,编译错误 void *p = static_cast<void*>(pn); //任意类型转换成void类型 } int main( int argc, char * argv[] ) { foo(); return 0; }
[b]dynamic_cast[/b]
说明:type-id必须是类的指针、类的引用或者void*,运行时会进行类型安全检查(转换失败返回NULL)。
场景:
基类和子类之间转换,上行和下行转换都是安全的。
基类必须要有虚函数。
交叉转换(相同基类的不同子类之间的转换),但结果是NULL。
#include <string.h> #include <iostream> using namespace std; class BaseClass { public: int m_data; virtual void btest(){}; //基类必须有虚函数 }; class DerivedClass : public BaseClass { public: char m_arr[100]; void dtest(){}; }; void foo() { BaseClass* pb = new DerivedClass(); DerivedClass *pd1 = static_cast<DerivedClass *>(pb); //子类->父类,静态类型转换,正确但不推荐 DerivedClass *pd2 = dynamic_cast<DerivedClass *>(pb); //子类->父类,动态类型转换,正确 BaseClass* pb2 = new BaseClass(); DerivedClass *pd3 = static_cast<DerivedClass *>(pb2); //父类->子类,静态类型转换,危险! //strcpy(pd3->m_arr, "0123456789"); //访问子类m_arr成员越界,造成运行时错误。 DerivedClass *pd4 = dynamic_cast<DerivedClass *>(pb2); //父类->子类,动态类型转换,安全。结果为NULL。 if (NULL == pd4) { cout << "null == pd4" << endl; } } int main( int argc, char * argv[] ) { foo(); return 0; }
[b]reinterpret_cast[/b]
说明:仅仅重新解释类型,但没有做字节对齐。
场景:最普通的用途就是在函数指针类型之间进行转换,但是很难保证移植性。
#include<iostream> using namespace std; class TestA { public: int m_a; }; class TestB { public: int m_b; }; class TestC : public TestA, public TestB {}; void foo() { TestC tc; cout << "&tc = 0x" << &tc << endl; cout << "reinterpret_cast<TestB*>(&tc) = 0x" << reinterpret_cast<TestB*>(&tc) << endl; cout << "static_cast<TestB*>(&tc) = 0x" << static_cast<TestB*>(&tc) << endl; } int main( int argc, char * argv[] ) { foo(); return 0; }
结果:
static_cast转换之后结果 - reinterpret_cast转换之后的结果 = 4(即该测试类中的字节对齐长度)。
说明:static_cast在进行上行转换是安全的,static_cast计算了父子类指针转换的偏移量,并将之转换到正确的地址,而reinterpret_cast则不会做这层转换。
[b]总结[/b]
const_cast:去const或volatile属性时用到。
static_cast:基本类型转换(不包括指针类型)时用到。
daynamic_cast:基类与子类的指针(或引用)互相转换时用到。
reinterpret_cast:不同类型的指针类型转换(如:函数指针类型之间进行转换),慎用。
[b]参考[/b]
http://baike.baidu.com/view/1745221.htm
http://baike.baidu.com/view/1745207.htm
http://baike.baidu.com/view/1745213.htm
http://baike.baidu.com/view/1263731.htm
http://www.cnblogs.com/goodhacker/archive/2011/07/20/2111996.html
(完)
相关文章推荐
- C++风格的强制类型转换之小结
- 用C++的静态和动态cast 替代C语言风格的老式的强制类型转换
- C++风格的类型转换操作符与C风格的强制类型转换
- C++新风格的强制类型转换(by Morphy, from csdn community)
- c++四种强制类型转换
- 我的 c++ 风格
- 设计Qt风格的C++的应用程序接口。
- 探讨C++实现一个不可被继承的类
- (读书笔记)C++中的强制类型转换
- 探讨C++中对象的“浅拷贝”与“深拷贝”
- 深入探讨C++中的引用
- 谷歌C++风格拾遗
- c++风格的string大小写转换
- 注释转换(C注释风格-C++注释风格)
- C++中的强制类型转换
- C++强制类型转换
- C++风格_注释
- C++风格_引用参数
- 深入探讨C++中的引用