C++四种类型转换cast,其在参数传递时的作用

  1. 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;
}
  1. 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;
}
  1. 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;
}
  1. 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;
}
相关推荐
郝学胜-神的一滴13 分钟前
Linux 多线程编程:深入理解 `pthread_join` 函数
linux·开发语言·jvm·数据结构·c++·程序人生·算法
Trouvaille ~15 分钟前
【C++篇】C++11新特性详解(二):右值引用与移动语义
c++·stl·基础语法·右值引用·默认成员函数·完美转发·移动语义
罗湖老棍子15 分钟前
瑞瑞的木板(洛谷P1334 )
c++·算法·优先队列·贪心·哈夫曼树
embrace9931 分钟前
【数据结构学习】数据结构和算法
c语言·数据结构·c++·学习·算法·链表·哈希算法
milan-xiao-tiejiang35 分钟前
ROS2面试准备
c++·面试·自动驾驶
杨恒9835 分钟前
GESPC++三级编程题 知识点
数据结构·c++·算法
week_泽1 小时前
题目 3330: 蓝桥杯2025年第十六届省赛真题-01 串
c++·贪心算法·蓝桥杯
历程里程碑1 小时前
LeetCode 283:原地移动零的优雅解法
java·c语言·开发语言·数据结构·c++·算法·leetcode
kupeThinkPoem1 小时前
std::thread的使用
c++