1、静态转换(static_cast)
static_cast包含的转换类型有
典型的非强制变换、
窄化(有信息丢失)变换、
使用void*的强制转换、
隐式类型变换、
类层次的静态定位。static_cast是编译器允许的。
(1)典型的非强制变换:
从窄类型向宽类型的转换,如char向short int,int,long int,float,double,long double的转换。
char a = 1;
long b = static_cast<long>(a);
(2)窄化变换:
与第1种相反,从宽类型向窄类型的变换。
long b = 1;
char a = static_cast<char>(b);
(3)使用void*的强制变换:
struct callback_param
{
void *vp;
};
int a = 1;
struct callback_param cp;
cp.vp = &a; //编译器允许从任意类型指针向void*转换
int *ip = static_cast<int *>(cp.vp);
(4)隐式类型转换:
包括(1)(2)
(5)类层次的静态定位
进行向上类型转换(派生类向基类转换)时,编译器清楚派生自什么祖先类,除了多继承(多继承转换后可能不为原地址,指针会在类层次中调整)。
2、常量转换(const_cast)
从const转换为非const,从volatile转换为非volatile。取得const对象的地址,会生成一个指向const的指针,volatile同。
const int i = 0;
int *ip = const_cast<int *>(&i);
volatile int a = 0;
int *ap = const_cast<int *>(&a);
3、重解释转换(reinterpret_cast)
interpret是解释的意思,reinterpret即为重新解释,此标识符的意思即为数据的二进制形式重新解释,但是不改变其值。如:
int i; char *ptr="hello freind!"; i=reinterpret_cast<int>(ptr);
这个转换方式很少使用。
最不安全的一种转换机制,将对象转变为完全不同类型的对象,这是低级的位操作。
struct msg_hdr
{
int msg_type;
int msg_len;
char msg_data[0];
};
struct msg_data
{
int data1;
int data2;
};
struct msg_hdr *p = reinterpret_cast<struct msg_hdr *>(recvbuf);
struct msg_data *pdata = reinterpret_cast<struct msg_data *>(p->msg_data);
4、动态转换(dynamic_cast)
类层次的向下转换(基类向派生类转换),转换过程中会通过RTTI检查转换类型是否正常,不正常将返回空。
该操作符用于运行时检查该转换是否类型安全,但只在多态类型时合法,即该类至少具有一个虚拟方法。dynamic_cast与static_cast具有相同的基本语法,dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
该操作符用于运行时检查该转换是否类型安全,但只在多态类型时合法,即该类至少具有一个虚拟方法。dynamic_cast与static_cast具有相同的基本语法,dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
#include <iostream>
using namespace std;
class pet
{
public:
virtual ~pet()
{
}
};
class dog : public pet
{
};
class cat : public pet
{
};
int main(void)
{
pet *b = new cat;
dog *d1 = dynamic_cast<dog *>(b);
cat *d2 = dynamic_cast<cat *>(b);
cout << "d1 = " << (long)d1 << endl; // d1 = 0
cout << "d2 = " << (long)d2 << endl;
}