dynamic_cast运算符,用于将基类的指针或引用安全地转换成派生类的指针或引用。
当我们将这两个运算符用于某种类型的指针或引用时,并且该类型含有虚函数,运算符将使用指针或引用所绑定对象的动态类型
类型转换名称和语法
c风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是:
TYPE b = (TYPE)a
c++风格的类型转换提供了4中类型转换操作符来应对不同场合的应用
static_cast 静态类型转换。如int转化成char
reinterpret_cast 重新解释类型
dynamic_cast 命名上理解是动态类型转换,如子类和父类之间的多态类型转换
const_cast 字面上理解就是去const属性
类型转换格式
TYPE b = static_cast<TYPE> a
类型转换介绍
static_cast<>() 静态类型转换,编译时c++编译器会做类型检查
若不同类型之间,进行强制类型转换,reinterpret_cast<>() 进行重新编译
dynamic_cast<>() 动态类型转换,安全的基类和子类之间转换,运行时类型检查
const_cast<>() 去除变量的只读属性
三种使用形式
dynamic_cast<type*> (e) //e必须为指针
dynamic_cast<type&> (e) // e 必须为一个左值
dynamic_cast<type&&> (e) //e不能是左值
#include <iostream>
using namespace std;
class Tree
{
};
class Animal
{
public:
virtual void cry()
{
}
};
class Dog:public Animal
{
public:
Dog():Animal()
{
age = 0;
}
virtual void cry()
{
cout << "汪汪 " << endl;
}
void doHome()
{
cout << "看家" << endl;
}
void printAge()
{
cout << age << endl;
}
private:
int age;
};
class Cat :public Animal
{
public:
virtual void cry()
{
cout << "喵喵 " << endl;
}
void doThing()
{
cout << "抓老鼠" << endl;
}
};
void playObj(Animal* base)
{
base->cry(); //有继承 虚函数重写 父类指针 指向子类对象 ==>多态
// dynamic_cast 运行时类型识别 RIIT
Dog *pDog = dynamic_cast<Dog*>(base); //父类对象 ===> 子类对象 向下转型
if (pDog != NULL)
{
pDog->doHome();
}
Cat *pCat = dynamic_cast<Cat*>(base);
if (pCat != NULL)
{
pCat->doThing();
}
}
//const char* p 的const 修饰 让p指向的内存空间 变成只读属性
void printBuf(const char* p)
{
//p[0] = 'Z';
char* p1 = NULL;
//要清楚知道 变量转换之前是什么类型 转换之后是什么类型
//const char* ===> char* //把只读属性去掉
p1 = const_cast<char*>(p);
p1[0] = 'Z'; //通过p1修改内存空间
cout << p << endl;
}
int main(int argc, char const *argv[])
{
char buf[] = "aaaaaaaaaaffffffffffdd";
const char* buf1 = "sssssssss"; //静态存储区 不能修改
//要确保传入参数所指向的内存空间能修改
printBuf(buf);
// printBuf(buf1); //会引起崩溃 不能修改
system("pause");
return 0;
}
int main2(int argc, char const *argv[])
{
Animal a;
Dog d;
Cat c;
Dog* d1 = static_cast<Dog*>(&a); //可以 有关联的可以转换
d1->cry();
d1->doHome();
d1->printAge();
playObj(&d);
playObj(&c);
Dog* d2 = NULL;
d2->doHome();
// d2->printAge(); 不能访问含有成员变量的成员函数 未分配内存
Animal* pBase = NULL;
pBase = &d;
pBase = static_cast<Animal*>(&d);
//强制类型转换
pBase = reinterpret_cast<Animal*>(&d);
{
Tree t;
//pBase = static_cast<Animal*>(&t); //c++编译器会做类型检查 无关的不通过
pBase = reinterpret_cast<Animal*>(&t); //reinterpret_cast 重新编译 强制类型转换
}
system("pause");
return 0;
}
int main1(int argc, char const *argv[])
{
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[20] = "hello...itcast\0";
int* p2 = NULL;
//p2 = static_cast<int*>(p1); //使用static_cast,编译器编译时,会做类型检查 若有错误 提示错误
p2 = reinterpret_cast<int*>(p1);
cout << "p1:" << p1 << endl; //%s
cout << "p2:" << p2 << endl; //%d 输出地址 根据类型输出
//总结:通过 reinterpret_cast<>() 和 static_cast<>() 把c语言的强制类型转换 都覆盖了
system("pause");
return 0;
}
本文截取 c++ primer 第五版 730页