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

C++从基类获取派生类实际类型:兼容多层继承的静态方法实现

不用C++23实现支持多层继承的CRTP引用计数类

核心问题分析

传统CRTP实现引用计数时,多层继承会导致每个继承层级都引入重复的count成员和方法歧义——因为每个基类实例都绑定到直接子类而非最终派生类。静态create方法需要准确识别最终派生类,才能正确分配对应类型的内存并初始化引用计数。

解决方案:带递归模板参数的CRTP

通过让Sharable模板接受一个“最终派生类”的模板参数,同时在多层继承中传递这个参数,确保所有层级共享同一个引用计数成员,且create方法能直接构造最终派生类。

实现代码示例

#include <cstdint>
#include <utility>

// 基础引用计数类,Final代表最终派生类
template<typename Final>
class Sharable {
protected:
    uint32_t ref_count = 0;

    // 构造函数保护,强制通过create创建对象
    Sharable() = default;
    Sharable(const Sharable&) = delete;
    Sharable& operator=(const Sharable&) = delete;

public:
    // 静态create方法,直接构造最终派生类
    template<typename... Args>
    static Final* create(Args&&... args) {
        Final* obj = new Final(std::forward<Args>(args)...);
        obj->ref_count = 1;
        return obj;
    }

    // 增加引用计数,返回最终派生类指针
    Final* dup() {
        ++ref_count;
        return static_cast<Final*>(this);
    }

    // 减少引用计数,计数为0时销毁对象
    void drop() {
        if (--ref_count == 0) {
            delete static_cast<Final*>(this);
        }
    }

    // 获取当前引用计数
    uint32_t get_ref_count() const {
        return ref_count;
    }
};

// 中间基类,必须传递Final参数给上层Sharable
template<typename Final>
class Intermediate : public Sharable<Final> {
protected:
    Intermediate() = default;
};

// 最终派生类,将自身作为Final参数传入
class Derived : public Intermediate<Derived> {
public:
    Derived(int val) : value(val) {}
    int value;
};

// 使用示例
int main() {
    Derived* obj = Derived::create(42);
    Derived* obj2 = obj->dup();
    obj->drop();
    obj2->drop(); // 计数归0,对象被销毁
    return 0;
}

关键细节说明

  • 递归模板参数传递:所有中间继承类必须将最终派生类Final传递给上层Sharable,确保所有层级共享同一个ref_count成员,避免重复定义。
  • 类型安全转换:通过static_cast<Final*>(this)确保dup和drop操作的是最终派生类实例,避免类型错误。
  • 自定义内存管理适配:如果需要替换内存分配逻辑,只需修改create方法中的new操作(比如换成自定义分配器或malloc),无需修改派生类代码。
  • 保护构造函数:强制对象只能通过create方法创建,保证引用计数从1开始初始化,避免未初始化的计数问题。

不推荐的替代方案:虚拟基类

虚拟基类可以解决成员重复问题,但会引入额外的虚表开销,且静态create方法仍需明确指定最终派生类,整体效率和简洁性远不如递归CRTP方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 00:10:58