介绍C++类型转换的用法。
1.static_cast
static_cast用与强制隐式类型转换,即隐式类型转换的反方向。static_cast,限制条件少,不进行运行时检验。
必须用于当你知道对象的具体类型时,这样检验是不必要的,否则,不安全。
example:
void func(void *data) {
// Conversion from MyClass* -> void* is implicit
MyClass *c = static_cast<MyClass*>(data);
...
}
int main() {
MyClass c;
start_thread(&func, &c) // func(&c) will be called
.join();
}
在这个例子中,你已经知道传入的是一个MyClass 对象,没有必要进行运行时检验。
如果将一个非MyClass 对象传入func中,会如何呢,看下面code,
#include<iostream>
using namespace std;
class A{
public:
A()
{
i=0;
j=12;
}
int i;
int j;
};
void cast_f(void *ptr)
{
A * p=static_cast<A *>(ptr);
cout<<p->i<<endl;
cout<<p->j<<endl;
}
int main()
{
int a=11;
int * p=&a;
cast_f(p);
cin.get();
return 0;
}
输出11和一个未知数。而不是0和12。 这就要我们确保已知传入的对象类型。否则,不安全。
2.dynamic_cast
dynamic_cast用在当你不知道对象的动态类型是什么的时候,而你想在一个你认定为继承类对象身上执行继承类的操作函数,但你的手上却只有一个指向基类对象的指针或者引用。若为downcast并且类型参数不为多态时,不能使用dynamic_cast,编译器报错。
dynamic_cast 返回一个null指针,如果对象的类型不是以将要转换为的类型为基类的话。即,非派生类对象转为基类对象,或者基类对象转为派生类对象,均返回null指针。
#include<iostream>
using namespace std;
class A{
public:
virtual void f(){
cout<<"A"<<endl;
}
};
class B:public A{
public:
void dynamic_f()
{
cout<<"called dynamic_f()"<<endl;
}
};
int main()
{
A a;
B *b=dynamic_cast<B *>(&a);//when downcast, if a is not object of class B,return null pointer.
if(!b)
{
cout<<"null"<<endl;
}
else
{
cout<<"not null"<<endl;
}
A *aa=0;//基类指针
B bb;
aa=&bb;//指向派生类
//aa如何调用dynamic_f()呢? aa.dynamic_f()当然不行了,编译不通过
B *ba=dynamic_cast<B*>(aa);
ba->dynamic_f();
cin.get();
return 0;
}
这个例子中,将基类对象转换为派生类对象,返回一个null指针。
up-cast(向上转换)是隐式转换,对static_cast,dynamic_cast,without any cast均有效。
3.Regular cast
Regular cast 又称为C风格类型转换。C-style cast,结合const_cast,static_cast,reinterpret_cast,但是它是不安全的,因为不支持dynamic_cast。
通常在数字转换时用C-style cast,其他用c++风格的cast。另外,c++风格的更易读。