在c++编程中,我们经常需要使用到类型转换,但可能不熟悉c++内置的四种类型转换操作符
它们分别是:const_cast、static_cast、dynamic_cast以及reinterpret_cast,它们的语法形式是统一的,type_cast_operator(expression)
const_cast主要用于解除常量或者常指针的const属性
static_cast主要用于基本类型之间的转换、基类对象指针和派生类对象指针之间的转换、一般指针类型和void*类型之间的转换
dynamic_cast运算符的type必须是一个类类型,其功能在于将一个基类的指针或引用安全的转换为派生类的指针或引用
reinterpret_cast是四种操作符中转换能力最强的操作符,它设置可以实现char *和class *的类型转换
const_cast是一种C++运算符,作用是去除复合类型中的const或volatile属性
变量本身的const属性是不能去掉的,要想修改常量的值,一般是去除指向该变量的指针(引用)的const属性
具体使用实例如下:
#include
using namespace std;
void constTest1()
{
const int a = 5;
int *p;
p = const_cast(&a); //如果写成p = &a;则会发生编译错误
(*p)++;
cout << "The a is:" << a << endl;
}
void constTest2()
{
int i;
cout << "请输入变量值:" << endl;
cin >> i;
const int a = i;
int &n = const_cast(a);
n++;
cout << "The n is:" << n << endl;
}
int main()
{
constTest1();
constTest2();
return 0;
}
程序运行结果如下:
The a is:5
请输入变量值:
8
The n is:9
虽然程序中constTest1函数输出的结果为5,但这并不能表明a的值没有改变,而是编译器将a优化为文字常量5
实际上a的值已经变成了6
在constTest2函数中,由于常变量无法转化为文字常量,所以它显示修改之后的值为6
static_const只能用于良性转换,风险很低;例如:原有的自动类型转换、void*和具体类型指针的转换或者用于类之间的转换
但需要注意的是,用于转换的类之间需要存在继承关系
static_const的具体使用实例如下:
#include
using namespace std;
class A{
public:
char c;
int num;
};
class B : public A{};
class C{};
int main()
{
A *a = new A;
char *p = static_cast(a);
B *b = new B;
a = static_cast(b);
C *c = new C;
a = static_cast(c);
}
程序运行结果如下:
typeChange.cpp:17:36: error: invalid static_cast from type 'A*' to type 'char*'
char *p = static_cast(a);
^
typeChange.cpp:23:26: error: invalid static_cast from type 'A*' to type 'C*'
c = static_cast(a);
^
以上程序报错原因如下:
将程序main函数改为以下内容即可编译通过:
int main()
{
A *a = new A;
//char *p = static_cast(a);
void *ptr = a;
char *p = static_cast(ptr);
B *b = new B;
a = static_cast(b);
C *c = new C;
//a = static_cast(c);
}
该操作符借助RTTI(运行时类型识别),通过运行时类型信息程序将够使用基类的指针安全的转化为派生类的指针或引用,因此它比static_cast更加安全
dynamic即支持向上转型,也允许向下转型。向上转型(派生类转换为基类)是无条件的,不需要进行任何检测,因此都能成功;向下转型的前提是安全,因此需要借助RTTI,是不一定能够成功的
dynamic_cast操作耗时较高,会影响程序性能,因此尽量少用
dynamic_cast使用实例:
#include
using namespace std;
class A{};
class B : public A{};
int main()
{
A *a = new A();
B *b = new B();
a = dynamic_cast(b);
if(b == NULL)
{
cout << "The dynamic_cast fail!!!" << endl;
}
else
{
cout << "The dynamic_cast success!!!" << endl;
}
}
reinterpret_cast一般是不提倡使用的,除非你确保这种操作是安全的
虽然reinterpret_cast的转换能力很强,但并非是万能的,编译器会设法最低限度的保证安全合理
其不支持的转换类型如下所示:
reinterpre_cast的使用实例如下:
#include
using namespace std;
typedef void (*pfunc)();
void func1()
{
cout << "This is func1(), return void" << endl;
}
int func2()
{
cout << "This is func2(), return int" << endl;
}
int main()
{
pfunc FuncArray[2];
FuncArray[0] = func1;
FuncArray[1] = reinterpret_cast(func2);
(*FuncArray[0])();
(*FuncArray[1])();
}
程序中typedef void (*pfunc)();语句的目的是定义新的数据类型pfunc,且该类型为函数指针,参数列表为空
typedef 返回值 (新类型)(参数列表)
程序运行结果如下所示:
This is func1(), return void
This is func2(), return int
根据程序运行结果得知,reinterpert_cast可以将函数指针int (* )()转化为void(* )(),其它操作符不能完成此操作
文章来源: 陈刚.C++高级进阶教程[M].武汉:武汉大学出版社,2008