- static_cast- 参数传递中的类型适配
基本数据类型转换
cpp
#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 -> double
processDouble(static_cast<double>(intValue)); // 输出: Processing double: 42
// 对比:隐式转换(也能工作,但不够明确)
processDouble(intValue);
return 0;
}
类层次结构中的上行转换
cpp
#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- 参数传递时的安全类型检查
安全的下行转换
cpp
#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,继续检查Cat
try {
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的兼容性处理
cpp
#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- 底层数据重新解释
序列化和网络编程中的应用
cpp
#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;
}
