C++有四种转型操作符,以下小结一下: 1,static_cast<>() 用得最多的,如果转换的是类型,则调用转型函数:比如int转float,float转int等基本数据类型的转型,如果是一个类,就调用类型转换函数,比如: #include <iostream> using namespace std; class A{public: explicit A(int _a = 0) : a(_a) {} operator int() const { return a; }private: int a;};int main(){ A a(100); int b = static_cast<int>(a); cout<<b<<endl; system("PAUSE"); return 0;}; 可以转换一个基类指针到子类指针的转型,但是不做动态类型检查,可以不存在虚函数,因此转型可能是不安全的,但是是快速的。 2,dynamic_cast<>() 专门用于C++类的指针转型,且是用于多态继承体系中的类。public继承体现了‘is-a’的类关系,一个基类指针,可以指向子类对象,它的子类类型是动态类型,dynamic_cast<>()就是将基类指针转型成它动态类型的子类指针,如果类型不对,结果就是空。 #include <iostream> using namespace std; class B{public: virtual void foo() { cout<<"B.foo"<<endl; }}; class D1 : public B{public: void foo() { cout<<"D1.foo"<<endl; } void foo2() { cout<<"D1.foo2"<<endl; }}; class D2 : public B{public: void foo() { cout<<"D2.foo"<<endl; } void foo3() { cout<<"D2.foo3"<<endl; }};int main(){ B *pb = new D2; pb->foo(); D1 *pd1 = dynamic_cast<D1*>(pb); if(pd1) { pd1->foo2(); } D2 *pd2 = dynamic_cast<D2*>(pb); if(pd2) { pd2->foo3(); } delete pb; system("PAUSE"); return 0;}; (1)必须有虚接口,那么,如果用基类指针使用虚接口,则可以动态绑定,不需要转型,就能体现多态;(2)如果是子类指针,可以直接给基类指针,可以直接使用。所以使用dynamic_cast的情形比较简单,就是用基类指针使用非虚接口的情形。非虚接口体现了子类的特有操作,也就是要确定它的动态类型,如上例,给了pb指针,但不知道是D1还是D2,转型后,看结果是否非空,如果空则表示不是这个类型,然后分情况处理。它相当于使用typeid+static_cast,是安全的转型。 3,const_cast<>() 用以去掉‘数据’的常量属性,常量属性多体现在指针和引用,因为如果没有指针和引用,就不存在不小心修改了不能修改的东西。如 const int a =314;a=2;//这个傻瓜编译器都知道你在忽悠它int *p = &a;*p=3;//这两句,是不是可以成功忽悠你,转了弯修改了不能修改的东西 C++会报错,因为&a是const int *,不能将一个const指针或引用赋给指针或初始化引用。换成这样就行了: int *p=const_cast<int*>(&a); 编译器放给了你这样的权力,如果你这样写,表明你能为它的后果负责,如果出了错,如果你做的是导弹火控系统,你将会知道结果有多严重。 MSDN里有一个例子,一个const成员函数里修改this指针的常量性,这很高明,真的很高明,因为完全没有理由使用mutable关键字啦~~const成员函数的第一个参数类型是const ClassName*,简单的不同。 4,reinterpret_cast 这个我用得非常少,因为太长了,每次打都不记得。字面意思是重新解释,就是可以将任何指针转型成其它指针或者整型类型,它是底层的转型,也是不安全的。MSDN里有一个hash函数的例子比较‘高层’的运用了它。哦,对了,它不能去掉const属性。 给一个我的例子,功能是显示数据的每一个字节: #include <cstdlib>#include <iostream> using namespace std; template<typename Functor>class for_byte{public: template<typename T> void operator()(T & data) { unsigned char * p = reinterpret_cast<unsigned char*>(&data); for(int i=sizeof(T);i>0;--i) { fun(*p++); } }private: Functor fun;}; struct display_bit{ void operator()(unsigned char byte) { printf("%02X",byte); }}; int main(int argc, char *argv[]){ for_byte<display_bit> display; double x = 3.14; int y = -1; display(x); printf("\n"); display(y); printf("\n"); display(display); printf("\n"); system("PAUSE"); return EXIT_SUCCESS;}

评论