一般来说,编译器隐式执行的任何类型转换都可以由static_cast显式完成。static_cast可以用来将枚举类型转换成整型,或者整型转换成浮点型。也可以用来将指向父类的指针转换成指向子类的指针。做这些转换前,你必须确定要转换的数据确实是目标类型的数据,因为static_cast不做运行时的类型检查以保证转换的安全性。也因此,static_cast不如dynamic_cast安全。对含有二义性的指针,dynamic_cast会转换失败,而static_cast却直接且粗暴地进行转换,这是非常危险的。
C++中的static_cast执行非多态的转换,基本等同于C风格的转换操作。对于我们的static_cast转换符,他不仅可以应用到指针和引用上,而且还可以应用到基础数据结构和对象上。
示例代码
class Entity
{
public:
virtual void PrintName() {}
};
class Player : public Entity
{
};
class Enemy : public Entity
{
public:
Enemy(int i) {}
};
int main()
{
double a = 5.22;
//int b = (int)(a); // C风格的显示转换
int b = static_cast<int>(a); // b = 5
int c = static_cast<int>(a + 5.33); // c = 10
Player* player = new Player();
Entity* actuallyPlayer = player;
Entity* actuallyEnemy = new Enemy();
Player* p0 = static_cast<Player*>(actuallyPlayer); // 转换成功,p0不是nullptr
Player* p1 = static_cast<Player*>(actuallyEnemy);// 转换成功,p1不是nullptr,但不安全,后面调用很可能出问题
Player p2 = static_cast<Player>(2); // 编译器报错
Enemy e = static_cast<Enemy>(2); // 正确,构造函数支持,实际暗中有隐式构造
std::cin.get();
}
总结
static_cast常用来进行基本类型直接的转换,如char与int、int与float、enum与int之间;
static_cast也可以转换用户自定义类型,但目标类型必须含有相应的构造函数;
static_cast还可以转换对象的指针类型,但它不进行运行时类型检查,所以是不安全的;
static_cast甚至可以把任何表达式都转换成void类型;
static_cast进行的是简单粗暴的转换,所以其正确性完全由程序员自己保证。