ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

深入理解C++ 类型转换<一>static_cast

深入理解C++ 类型转换<一>static_cast 什么是 static_caststatic_cast是 C 中最常用的编译时类型转换运算符。它的核心逻辑是“编译期静态检查”——编译器在编译代码时根据已有的类型信息判断这个转换是否“说得通”如果说得通就通过说不通就报错。关键特性零运行时开销它不会像dynamic_cast那样在运行时去检查类型是否合法纯粹是编译期的指令重解释因此性能最高。有“常识”限制它只能用于有明确定义的转换如数值之间、继承关系的指针、void*等。它不能去掉const属性那是const_cast的事也不能把完全不相关的类型如int*转float*强行捏在一起那是reinterpret_cast的事。最常见的 4 种使用场景基本数值类型转换最安全如int转doubledouble转int注意精度丢失。类层次结构中的向上转换子类 → 父类安全编译器通常也能隐式做但显式写出来可读性更好。类层次结构中的向下转换父类 → 子类没有运行时检查需要程序员自己确保父类指针确实指向的是该子类对象否则会引发未定义行为UB。void*与具体类型指针互转C 语言风格的常见操作用static_cast更规范。#include iostream // 1. 定义一个简单的继承体系用于演示类转换 class Animal { public: virtual ~Animal() default; // 加虚析构让类变成多态类型虽然这里没用到 dynamic_cast但是好习惯 void speak() const { std::cout Animal sound std::endl; } }; class Dog : public Animal { public: void wagTail() const { std::cout Dog wags tail std::endl; } // 重写 speak但为了演示指针转换我们不把它设为 virtual避免干扰理解 }; class Cat : public Animal { public: void meow() const { std::cout Cat meows std::endl; } }; int main() { std::cout 1. 基本数值类型转换 std::endl; int a 10; int b 3; // 如果不转10/3 得 3转为 double 后得 3.333... double result static_castdouble(a) / b; std::cout 10 / 3 result std::endl; // 大范围转小范围注意精度截断 double pi 3.14159; int intPi static_castint(pi); std::cout double 3.14159 转为 int intPi std::endl; std::cout \n 2. 向上转换子类 - 父类 std::endl; Dog dog; // 将 Dog* 转为 Animal*这是绝对安全的子类一定包含父类的全部 Animal* animalPtr static_castAnimal*(dog); animalPtr-speak(); // 输出 Animal sound std::cout 向上转换成功 std::endl; std::cout \n 3. 向下转换父类 - 子类 std::endl; // 注意这里 animalPtr 实际上指向的是 Dog 对象所以向下转是安全的 Dog* dogPtr static_castDog*(animalPtr); dogPtr-wagTail(); // 正常输出 // 【危险示范】如果父类指针实际指向的是 Cat强行转为 Dog 会怎样 Cat cat; Animal* animalPtrToCat cat; Dog* wrongDogPtr static_castDog*(animalPtrToCat); // 编译通过但运行时不报错行为是未定义的UB。 // 下面这行代码可能会崩溃也可能输出乱码或者看似正常但实际污染内存 // 为了演示安全我们注释掉这行避免你的程序崩溃 // wrongDogPtr-wagTail(); std::cout static_cast 向下转换没有运行时检查开发者必须自己保证类型正确 std::endl; std::cout \n 4. void* 与具体类型互转 std::endl; int value 100; void* voidPtr value; // 任何指针都能赋值给 void* // 从 void* 还原为 int*必须用 static_cast int* recoveredPtr static_castint*(voidPtr); std::cout 从 void* 还原的值: *recoveredPtr std::endl; return 0; }
返回列表