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;
}
评论