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;
}
//结果
//p=aaaaa;
//p=ataaa