C++四种类型转换cast,其在参数传递时的作用
- static_cast- 参数传递中的类型适配
基本数据类型转换
#include <iostream>void processDouble(double d) {std::cout << "Processing double: " << d << std::endl;
}void processBase(class Base* b) {std::cout << "Processing Base object" << std::endl;
}int main() {int intValue = 42;// 在参数传递时进行static_cast:int -> doubleprocessDouble(static_cast<double>(intValue)); // 输出: Processing double: 42// 对比:隐式转换(也能工作,但不够明确)processDouble(intValue);return 0;
}
类层次结构中的上行转换
#include <iostream>class Base {
public:virtual void display() { std::cout << "Base class" << std::endl; }virtual ~Base() = default;
};class Derived : public Base {
public:void display() override { std::cout << "Derived class" << std::endl; }void specificFunction() {std::cout << "Derived specific function" << std::endl;}
};// 函数接受Base指针参数
void processObject(Base* obj) {obj->display(); // 多态调用
}void processObjects(Base** objects, int count) {for (int i = 0; i < count; ++i) {objects[i]->display();}
}int main() {Derived derivedObj;// 上行转换:Derived* -> Base*(安全)processObject(static_cast<Base*>(&derivedObj)); // 输出: Derived class// 在数组参数传递中的使用Derived* derivedArray[3];for (int i = 0; i < 3; ++i) {derivedArray[i] = new Derived();}// 需要将Derived**转换为Base**processObjects(static_cast<Base**>(derivedArray), 3);// 清理内存for (int i = 0; i < 3; ++i) {delete derivedArray[i];}return 0;
}
- dynamic_cast- 参数传递时的安全类型检查
安全的下行转换
#include <iostream>
#include <typeinfo>class Animal {
public:virtual void speak() = 0;virtual ~Animal() = default;
};class Dog : public Animal {
public:void speak() override {std::cout << "Woof!" << std::endl;}void fetch() {std::cout << "Fetching ball..." << std::endl;}
};class Cat : public Animal {
public:void speak() override {std::cout << "Meow!" << std::endl;}void climb() {std::cout << "Climbing tree..." << std::endl;}
};// 处理Animal参数的函数
void processAnimal(Animal* animal) {animal->speak();// 使用dynamic_cast进行安全的类型检查Dog* dog = dynamic_cast<Dog*>(animal);if (dog != nullptr) {std::cout << "It's a Dog! ";dog->fetch();}Cat* cat = dynamic_cast<Cat*>(animal);if (cat != nullptr) {std::cout << "It's a Cat! ";cat->climb();}
}// 使用引用参数的版本(失败时抛出异常)
void processAnimalRef(Animal& animal) {try {Dog& dog = dynamic_cast<Dog&>(animal);std::cout << "Definitely a Dog! ";dog.fetch();}catch (const std::bad_cast& e) {// 不是Dog,继续检查Cattry {Cat& cat = dynamic_cast<Cat&>(animal);std::cout << "Definitely a Cat! ";cat.climb();}catch (const std::bad_cast& e) {std::cout << "Unknown animal type" << std::endl;}}
}int main() {Dog dog;Cat cat;std::cout << "=== Processing Dog ===" << std::endl;processAnimal(&dog);std::cout << "\n=== Processing Cat ===" << std::endl;processAnimal(&cat);std::cout << "\n=== Using reference version ===" << std::endl;processAnimalRef(dog);processAnimalRef(cat);return 0;
}
- const_cast- 参数传递中的常量性修改
调用旧式API的兼容性处理
#include <iostream>
#include <cstring>// 旧式C函数,参数是非const的(但实际不会修改)
void legacyCFunction(char* buffer) {// 这个函数声明时没有用const,但实际是只读的std::cout << "Legacy function processing: " << buffer << std::endl;
}// 现代C++函数,正确使用const
void modernFunction(const char* buffer) {std::cout << "Modern function processing: " << buffer << std::endl;// 需要调用旧式API,但旧API需要非const参数// 使用const_cast来移除const(因为我们知道legacyCFunction不会修改数据)legacyCFunction(const_cast<char*>(buffer));
}// 重载函数示例
class Logger {
public:// const版本void log(const std::string& message) const {std::cout << "LOG: " << message << std::endl;}// 非const版本,内部需要修改一些缓存但对外表现是const的void log(const std::string& message) {// 在非const版本中调用const版本以避免代码重复const_cast<const Logger*>(this)->log(message);// 然后可以执行一些非const的操作updateCache();}private:void updateCache() {// 更新一些内部缓存std::cout << "Updating cache..." << std::endl;}
};// 错误示例:修改真正的const对象
void dangerousExample() {const int immutable = 100;const int* constPtr = &immutable;// 危险!未定义行为!int* dangerousPtr = const_cast<int*>(constPtr);*dangerousPtr = 200; // 这可能导致程序崩溃或不可预测行为std::cout << "immutable = " << immutable << std::endl; // 可能还是100!std::cout << "*dangerousPtr = " << *dangerousPtr << std::endl; // 可能是200
}int main() {const char* message = "Hello, World!";std::cout << "=== Safe const_cast usage ===" << std::endl;modernFunction(message);std::cout << "\n=== Logger example ===" << std::endl;Logger logger;const Logger constLogger;logger.log("Non-const logger"); // 调用非const版本constLogger.log("Const logger"); // 调用const版本std::cout << "\n=== Dangerous example (未定义行为) ===" << std::endl;// dangerousExample(); // 取消注释会导致未定义行为return 0;
}
- reinterpret_cast- 底层数据重新解释
序列化和网络编程中的应用
#include <iostream>
#include <cstring>
#include <cstdint>// 网络数据包结构
struct NetworkPacket {uint32_t header;uint16_t dataLength;char payload[100];
};// 序列化函数:将对象转换为字节流
template<typename T>
void serializeToBytes(const T& obj, char* buffer) {// 使用reinterpret_cast将对象指针转换为char指针进行字节操作const char* bytePtr = reinterpret_cast<const char*>(&obj);std::memcpy(buffer, bytePtr, sizeof(T));
}// 反序列化函数:将字节流转换回对象
template<typename T>
T deserializeFromBytes(const char* buffer) {T obj;char* bytePtr = reinterpret_cast<char*>(&obj);std::memcpy(bytePtr, buffer, sizeof(T));return obj;
}// 函数指针类型转换(跨DLL边界等场景)
typedef void (*SimpleFunction)();
typedef int (*ComplexFunction)(int, double);void simpleFunc() {std::cout << "Simple function called" << std::endl;
}int complexFunc(int a, double b) {std::cout << "Complex function: " << a << ", " << b << std::endl;return a + static_cast<int>(b);
}// 回调函数处理(模拟系统API)
void registerCallback(void* callback, int type) {if (type == 0) {SimpleFunction func = reinterpret_cast<SimpleFunction>(callback);func();} else {ComplexFunction func = reinterpret_cast<ComplexFunction>(callback);int result = func(10, 3.14);std::cout << "Callback result: " << result << std::endl;}
}// 危险示例:错误的类型重新解释
void dangerousReinterpret() {double d = 3.14159;std::cout << "Original double: " << d << std::endl;// 将double*重新解释为int*int* intPtr = reinterpret_cast<int*>(&d);std::cout << "First 4 bytes as int: " << *intPtr << std::endl;// 这是极度危险的!违反了严格别名规则*intPtr = 0; // 可能破坏double的内存表示std::cout << "Corrupted double: " << d << std::endl; // 未定义行为!
}int main() {std::cout << "=== 序列化/反序列化示例 ===" << std::endl;NetworkPacket originalPacket{0x12345678, 50, "Hello Network!"};char buffer[sizeof(NetworkPacket)];serializeToBytes(originalPacket, buffer);NetworkPacket restoredPacket = deserializeFromBytes<NetworkPacket>(buffer);std::cout << "Header: 0x" << std::hex << restoredPacket.header << ", Data: " << restoredPacket.payload << std::dec << std::endl;std::cout << "\n=== 函数指针转换示例 ===" << std::endl;// 注册不同类型的回调函数registerCallback(reinterpret_cast<void*>(simpleFunc), 0);registerCallback(reinterpret_cast<void*>(complexFunc), 1);std::cout << "\n=== 指针和整数转换示例 ===" << std::endl;int value = 42;int* ptr = &value;// 将指针转换为整数(用于存储或传输)uintptr_t intValue = reinterpret_cast<uintptr_t>(ptr);std::cout << "Pointer as integer: " << intValue << std::endl;// 将整数转换回指针int* restoredPtr = reinterpret_cast<int*>(intValue);std::cout << "Restored pointer value: " << *restoredPtr << std::endl;std::cout << "\n=== 危险示例(注释掉) ===" << std::endl;// dangerousReinterpret(); // 取消注释会导致未定义行为return 0;
}

