1. static_cast
具有明确定义的类型转换,只要不包含底层const
int i = 10;
double d = static_cast<double>(i);
std::cout << d << std::endl;
void* p = &d;
double* pD = static_cast<double*>(p);
std::cout << *pD << std::endl;
2. const_cast
只改变底层const(指针指向的对象),但若对象是常量,写操作的结果是未定义的,常用于有函数重载的上下文。
const char* pc = "hello";
char* pstr = const_cast<char*>(pc);
3. dynamic_cast
RTTI(运行时类型识别)功能由两个运算符实现:typeid & dynamic_cast
基类指针/引用安全地转换为派生类的,使用指针绑定的对象的动态类型【基类指针/引用调用派生类方法(非虚函数)】。
转换指针失败返回0,转换引用失败抛出 std::bad_cast 异常。
class Entity {
public:
virtual void PrintName() {
}
};
class Player :public Entity
{
public:
void PlayerShoot() {
std::cout << "shoot" << std::endl;
}
};
class Enemy :public Entity
{
public:
void EnemyRun() {
std::cout << "run" << std::endl;
}
};
void test()
{
Entity* actualEnemy = new Enemy();
Entity* actualPlayer = new Player();
if (dynamic_cast<Player*>(actualPlayer)) {
std::cout << "actualEnemy is a player" << std::endl;
}
else
{
std::cout << "actualEnemy is not a player" << std::endl;
}
Entity* actualEntity = new Entity();
if (dynamic_cast<Player*>(actualEntity)) {
std::cout << "actualEntity is a player" << std::endl;
}
Player* player = dynamic_cast<Player*>(actualEntity);
//player->PrintName(); -> 可以通过null指针调用普通的类型成员函数,但是不能调用虚函数
player->PlayerShoot();
}
注意:可以通过 null 指针调用普通的成员函数,而非虚函数!😄😁😋
4. reinterpret_cast
通常为运算对象的位模式提供较低层次上的重新解释。
int *ip;
char *pc = reinterpret_cast<char*>(ip);
//但 pc 所指真实对象是 int,而非字符,若当作字符指针使用则可能发生错误
// string str(pc);
“使用 reinterpret_cast 是很危险的”