You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++如何校验FifoObject中void*到目标类型的static_cast转换安全性

解决方案

核心思路是新增运行时类型信息存储,结合多态类型的动态转换校验,既满足类型安全要求,也不需要修改现有类的继承结构,适配C++20语法特性。
修改后的完整实现如下:

#include <typeinfo>
#include <cassert>
#include <functional>
#include <memory>
#include <type_traits>

class FifoObject final
{
public:
    FifoObject() = default;

    template<typename T>
    FifoObject(std::unique_ptr<T>& obj):
        freeData(static_cast<void*>(obj.release())),
        deleteObject([](void* data) { delete static_cast<T*>(data); }),
        m_srcType(&typeid(T))
    {}

    ~FifoObject()
    {
        if (freeData != nullptr) {
            deleteObject(freeData);
        }
    }

    // C++20 Concept 编译期拦截非法类型参数,可按需开启
    // template<typename T>
    // concept FifoStorable = std::is_object_v<T> && std::is_destructible_v<T>;
    // template<FifoStorable T>
    template<typename T>
    inline T* release() 
    {
        if (!freeData) {
            return nullptr;
        }

        // 1. 优先精确类型匹配,无额外运行时开销
        if (*m_srcType == typeid(T)) {
            T* ret = static_cast<T*>(freeData);
            freeData = nullptr;
            return ret;
        }

        // 2. 多态类型场景,自动校验基类/派生类转换合法性
        if constexpr (std::is_polymorphic_v<T>) {
            // 动态转换获取最派生对象地址,和存储地址比对确认转换合法性
            void* mostDerivedAddr = dynamic_cast<void*>(static_cast<T*>(freeData));
            if (mostDerivedAddr == freeData) {
                T* ret = static_cast<T*>(freeData);
                freeData = nullptr;
                return ret;
            }
        }

        // 类型不匹配,Debug模式断言,Release模式返回空指针供上层处理
        assert(false && "FifoObject release 类型不匹配");
        return nullptr;
    }

    // 直接获取存储对象的类名,满足调试需求
    const char* getStoredTypeName() const {
        return m_srcType ? m_srcType->name() : "empty";
    }

private:
    void* freeData = nullptr;
    std::function<void(void* data)> deleteObject;
    std::type_info const* m_srcType = nullptr;
};

逻辑说明

  • 精确类型检查:存入时记录原始类型的std::type_info指针,release时优先做精确匹配,没有额外运行时开销。
  • 多态类型兼容:如果目标类型是多态类型(包含虚函数),会通过dynamic_cast校验转换合法性,自动处理基类、派生类之间的内存偏移问题,即使存在多继承也能正常工作。
  • 性能可控:Debug模式下类型不匹配会直接断言定位问题,Release模式下可以关闭断言提升性能,也可以保留判断返回空指针做上层错误处理。
  • 完全符合你的限制条件:FifoObject不是模板类可直接存入数组,不需要修改现有类继承结构,无需依赖std::any/std::variant/shared_ptr<void>。

边界场景说明

  • 非多态类型(无虚函数的类)只支持精确类型匹配,因为没有运行时类型信息,无法校验基类派生类关系。如果需要对非多态类型做基类转换,存入时显式将unique_ptr转为基类类型再存入即可。
  • 不同编译器对type_info::name()的输出格式略有差异,但足够用于定位类型不匹配问题。

内容的提问来源于stack exchange,提问作者Juan JuezSarmiento

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 01:36:05