C++四种类型转换
C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是:
TYPE b = (TYPE)a
C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用。
static_cast 静态类型转换。如int转换成char
reinterpreter_cast 重新解释类型
dynamic_cast 命名上理解是动态类型转换。如子类和父类之间的多态类型转换。
const_cast, 字面上理解就是去const属性。
4种类型转换的格式:
TYPE B = static_cast<TYPE> (a)
一般性介绍
1)static_cast<>() 静态类型转换,编译的时c++编译器会做类型检查;
基本类型能转换 但是不能转换指针类型
2)若不同类型之间,进行强制类型转换,用reinterpret_cast<>() 进行重新解释
3)一般性结论:
C语言中 能隐式类型转换的,在c++中可用 static_cast<>()进行类型转换。因C++编译器在编译检查一般都能通过;
C语言中不能隐式类型转换的,在c++中可以用 reinterpret_cast<>() 进行强行类型 解释。总结:static_cast<>()和reinterpret_cast<>() 基本上把C语言中的 强制类型转换给覆盖
reinterpret_cast<>()很难保证移植性。
4)dynamic_cast<>(),动态类型转换,安全的基类和子类之间转换;运行时类型检查
5)const_cast<>(),去除变量的只读属性
典型案例
static_cast和reinterpreter_cast
#include <iostream> using namespace std; int main() { double dpi = 3.1415926; int num1 = (int)dpi; // c类型转换 int num2 = static_cast<int> (dpi); // c++静态类型转换, 编译时编译器会进行类型检查 int num3 = dpi; // c语言中,隐士类型转换的地方,去可以使用,有警告,但是加上Static_cast就没了 // char* ===> int* char *p1 = "hello world"; int *p2 = NULL; // p2 = static_cast<int*>(p1); // 编译器会进行类型检查,有错就提示出来 p2 = reinterpret_cast<int*> (p1); cout << "p1 = " << p1 <<endl; //%s 一个字符串,如果是*p1就是h cout << "p2 = " << p2 << endl; //%d 字符串的首地址 // 总结:通过reinterpreter_cast<>(),static_cast<>(),把c语言中的强制类型都覆盖了 return 0; }
//结果
//p1 = hello world
//p2 = 0x47f048
dynamic_cast用法和reinterpret_cast用法
#include <iostream> using namespace std; /* C分格的强制类型转换(Type cast),很简单,不管什么类型,都是 Type b = (Type)a; C++风格提供了4种类型转换操作符,来对应不同的场合的应用 static_cast 静态类型转换,如int转换成char reinterpreter_cast 重新解释类型 dynamic_cast 命名上理解动态类型转换,如子类和父类之间的多态类型转换 const_cast 字面理解就是const属性 4中类型转换格式: Type b = static_cast<Type> (a); */ class Animal { public: virtual void cry() = 0; }; class Dog : public Animal { public: virtual void cry() // 虚函数重写 { cout <<"\t汪汪" << endl; } void doHome() { cout << "\t看家" << endl; } }; class Cat : public Animal { public: virtual void cry() { cout << "\t喵喵" <<endl; } void doThing() { cout << "\t抓老鼠" << endl; } }; // 对象唱戏,发生多态, 只能用指针或者引用 void playObj(Animal &base) { base.cry(); // 1有继承, 2 虚函数重写,3父类指针(引用) 指向子类对象 ===> 发生多态 cout << endl; // 需求:识别子类对象 // dynamic_cast 运行时类型识别 Dog *pDog = dynamic_cast<Dog *> (&base); if (pDog != NULL) { pDog->doHome(); // 做自己特有的工作 } cout << endl; Cat *c1 = dynamic_cast<Cat *> (&base); // 父类对象 ==> 子类对象 // 向下转型 // 把老子转成小子 if (c1 != NULL) { c1->doThing(); } } class Tree{}; int main() { Dog d1; Cat c1; Animal *pBase = NULL; pBase = &d1; pBase = static_cast<Animal*>(&d1); // c++编译时,进行类型检查,将d1指针转换成父类指针 // 强制类型转换 pBase = reinterpret_cast<Animal*>(&d1); { Tree t1; // 将树指针 转换成动物类指针 // pBase = static_cast<Animal*> (&t1); // c++编译器,类型检查 不通过 pBase = reinterpret_cast<Animal*> (&t1); // 可以 重新解释。。。。强制类型转换的味道 } playObj(d1); playObj(c1); return 0; }
//结果
// 汪汪
//
// 看家
//
// 喵喵
//
//
// 抓老鼠
const_cast用法
// const char*p,中得const表示 p指向的内存空间 不可以修改 就是*p(值)不能改 void printBuf(const char*p) { // p[0] = 't'; 报错 char *p1 = NULL; // 程序员要清楚地知道:变量转换前,和转换后的类型 p1 = const_cast<char*>(p); // 将p 由const char* == > char* cout << "p = " << p << endl; p1[1] = 't'; // 通过p1修改了 p指向的内存空间 // 转换后 可以间接修改p的值,不准换的话,也不能间接修改 cout << "p = " << p << endl; } int main() { char buf[] = "aaaaa"; // 程序员 要确保 p所指向的内存空间,确实能修改,如果不能修改,会带来灾难性的后果 printBuf(buf); // char *myBuf = "bbbbbbbb"; // 常量,不能修改 // printBuf(myBuf); return 0; }