类型转换
一、类型转换的名称和语法
类型转换有 c 风格的,当然还有 c++风格的。c 风格的转换的格式很简单(TYPE) EXPRESSION,但是 c 风格的类型转换有不少的缺点,有的时候用 c 风格的转换是不合 适的,因为它可以在任意类型之间转换,比如你可以把一个指向const 对象的指针转换 成指向非 const 对象的指针,把一个指向基类对象的指针转换成指向一个派生类对象的 指针,这两种转换之间的差别是巨大的,但是传统的 c 语言风格的类型转换没有区分这 些。还有一个缺点就是,c 风格的转换不容易查找,他由一个括号加上一个标识符组成, 而这样的东西在 c++程序里一大堆。所以 c++为了克服这些缺点,引进了 4 新的类型转换操作符。
C语言的强制类型转换(Type Cast)
TYPE b = (TYPE)a
C++提供了4类类型转换,分别处理不同的场合应用
static_cast 静态转换类型
reinterpret_cast 重新解释类型转换、
dynamic_cast 子类和父类之间的多态类型转换
const_cast 去掉const属性转换
二、转换方式
1.static_cast 静态类型转换
static_cast<目标类型> (标识符)
所谓静态,即在编译器内即可决定其类型类型的转换,用的也是最多的一种。
static_cast用于内置的数据类型,还有具有继承关系的指针或引用的转换。
2.dynamic_cast 子类和父类之间的多态类型转换
dynamic_cast<目标类型> (标识符)
用于多态中的父子类之间的强制转化,并且只能由子类型转换成父类型。
3.const_cast 增加或者去除变量的const属性
const_cast<目标类型>(标识符)//目标类类型只能是指针或引用。
4.reinterpret_cast 重新解释类型转换
reinterpret_cast<目标类型> (标识符)
interpret 是解释的意思,reinterpret 即为重新解释,此标识符的意思即为数据的二进制形式重新解释,但是不改变其值。
代码:
#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; class Building{}; class Animal{}; class Cat:public Animal{}; //static_cast void test1() { //基础数据类型 int a = 99; char c = static_cast<char>(a); //基础数据类型指针 //int* p = NULL; //char* sp = static_cast<char*>(p);//error //对象指针 //Building* building = NULL; //Animal* ani = static_cast<Animal*>(building);//error //转换具有继承关系的对象指针 //父类指针转成子类指针 Animal* ani = NULL; Cat* cat1 = static_cast<Cat*>(ani); //子类指针转成父类指针 Cat* soncat = NULL; Animal* anifather = static_cast<Animal*>(soncat); Animal aniobj; Animal& aniref = aniobj; Cat& cat2 = static_cast<Cat&>(aniref); Cat catobj; Cat& catref = catobj; Animal& anifather2 = static_cast<Animal&>(catref); //结论:static_cast用于内置的数据类型,还有具有继承关系的指针或引用的转换。 } //dynamic_cast 转换具有继承关系的指针或引用,在转换前会进行对象类型检查 void test2() { //基础数据类型 //int a = 10; //char c = dynamic_cast<char>(a);//error //非继承关系的指针 //Animal* ani = NULL; //Building* building = dynamic_cast<Building*>(ani);//error //具有继承关系指针 //Animal* ani = NULL; //Cat* cat = dynamic_cast<Cat*>(ani);//error //报错原因在于 dynamic_cast做类型安全检查, //父类指针可以转换成子类指针(从小到大),类型不安全 Cat* cat = NULL; Animal* ani = dynamic_cast<Animal*>(cat); //子类指针可以转换成父类指针(从大到小),类型安全 //结论:dynamic_cast只能转换具有继承关系的指针或引用,并且只能由子类型转换成基类型 } //const_cast 指针、引用或者对象指针 void test3() { //基础数据类型 int a = 10; const int& b = a; int& c = const_cast<int&>(b); c = 20;//此时c可以进行修改 cout << "a:" << a << endl;//a:20 cout << "b:" << b << endl;//b:20 cout << "c:" << c << endl;//c:20 //看指针 const int* p = NULL; int* p2 = const_cast<int*>(p); int* p3 = NULL; const int* p4 = const_cast<const int*>(p3); //const_cast作用:增加或者去除变量的const属性 } //reinterpret_cast 强制类型转换 typedef void(*FUNC1)(int, int); typedef int(*FUNC2)(int, char*); void test4() { //1.无关的指针类型都可以进行转换 Building* building = NULL; Animal* ani = reinterpret_cast<Animal*>(building); //2.函数指针转换 FUNC1 func1; FUNC2 func2 = reinterpret_cast<FUNC2>(func1); } int main(void) { test1(); test2(); test3(); test4(); return 0; }
结论
结论1.
程序员要清除的知道:要转的变量,类型转换前是什么类型,类型转换后是什么类型。转换后有什么后果。
结论2.
一般情况下,不建议进行类型转换。