C++ 强制类型转换总结
- 简介
- static_cast
- 介绍
- 场景
- 示例
- dynamic_cast
- 介绍
- 场景
- 示例
- const_cast
- 介绍
- 示例
- reinterpret_cast
- 介绍
- 特点
- 示例
简介
在开发时候,对强制类型转换经常感觉很迷糊,什么场景用哪个没有一个确切的认识,因此借着这个机会好好总结下,下面我们开始来分析吧。
static_cast
介绍
static_cast 是最常用的类型转换运算符,用于执行非多态类型的转换。不执行运行时类型检查(转换安全性不如 dynamic_cast)
场景
- 用来进行基本数据类型之间的转换,如整型和浮点型,
- 在类层次结构中进行上行和下行转换(只要不存在虚继承),下行(把基类指针转换为子类指针)转换不安全
示例
#include <iostream>int main() {double d = 9.5;int i = static_cast<int>(d); // 将 double 转换为 intstd::cout << i << std::endl; // 输出 9// 类层次结构的转换class Base {};class Derived : public Base {};Derived* derived = new Derived();Base* base = static_cast<Base*>(derived); // 安全的上行转换Derived* newDerived = static_cast<Derived*>(base); // 不安全的下行转换return 0;
}
dynamic_cast
介绍
dynamic_cast 用于处理具有多态性的类型转换,主要用于类层次结构中的安全向下转换。它在运行时检查对象类型,确保转换的安全性。如果转换失败,对于指针类型返回 nullptr,对于引用类型抛出异常。
场景
- 用于具有多态性的类型转换,主要用于类层次结构中的安全向下转换
- 只适用于指针或引用
- 可以在整个类层次结构中移动指针,包括向上转换、向下转换
示例
#include <iostream>class Base {
public:virtual void print() { std::cout << "Base class" << std::endl; }virtual ~Base() {}
};class Derived : public Base {
public:void print() override { std::cout << "Derived class" << std::endl; }
};int main() {Base* base = new Derived();Derived* derived = dynamic_cast<Derived*>(base);if (derived) {derived->print(); // 输出 "Derived class"}delete base;return 0;
}
const_cast
介绍
用于删除 const、volatile 和 __unaligned 特性(如将 const int 类型转换为 int 类型 )
示例
#include <iostream>void print(char* str) {std::cout << str << std::endl;
}int main() {const char* cStr = "Hello, world!";char* modifiableStr = const_cast<char*>(cStr);print(modifiableStr); // 输出 "Hello, world!"return 0;
}
reinterpret_cast
介绍
reinterpret_cast 用于进行低级别的重新解释转换,它可以将任何指针类型转换为任何其他指针类型,甚至可以将指针转换为足够大的整型。这种转换是不安全的,应谨慎使用。
特点
- 用于位的简单重新解释
- 滥用 reinterpret_cast 运算符可能很容易带来风险。 除非所需转换本身是低级别的,否则应使用其他强制转换运算符之一。
- 允许将任何指针转换为任何其他指针类型(如 char* 到 int* 或 One_class* 到 Unrelated_class* 之类的转换,但其本身并不安全)
- 也允许将任何整数类型转换为任何指针类型以及反向转换。
- reinterpret_cast 运算符不能丢掉 const、volatile 或 __unaligned 特性。
- reinterpret_cast 的一个实际用途是在哈希函数中,即,通过让两个不同的值几乎不以相同的索引结尾的方式将值映射到索引。
哈希函数是将任意长度的数据映射到固定长度的值(称为哈希值)的一种算法。在使用哈希表(hash table)这种数据结构时,哈希函数起到了关键作用。哈希表通过哈希函数将键值映射到数组中的索引,然后在该索引位置存储相关的值。
理想情况下,哈希函数应该能够将不同的输入值映射到尽可能分散的输出索引,这样可以避免冲突(即不同键值映射到同一个索引)的发生,提高哈希表的查询性能。
这就是 reinterpret_cast 在哈希函数中的用途:利用它可以将不同的输入值转换成不同的比特模式,从而使哈希函数生成的索引更加分散。例如,可以将整数或浮点数通过 reinterpret_cast 转换成字节序列,然后将这些字节序列作为哈希函数的输入,以获得更加均匀分散的索引分布。
总之,reinterpret_cast 在哈希函数中的作用是提高哈希值的分散性,从而减少哈希冲突,提高哈希表的性能。这是该类型转换的一个重要应用场景。
示例
#include <iostream>int main() {int a = 42;int* aPtr = &a;char* charPtr = reinterpret_cast<char*>(aPtr);std::cout << *charPtr << std::endl; // 可能输出不确定的结果,取决于系统和编译器uintptr_t p = reinterpret_cast<uintptr_t>(aPtr);std::cout << p << std::endl; // 输出指针的整数值return 0;
}