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

如何在C++中为派生类实现Create()函数

解决方案

要让Create()函数支持派生类,同时复用基类的ID生成逻辑,可以通过**奇异递归模板模式(CRTP)**实现,同时调整基类构造函数的访问权限。以下是具体实现:

1. 调整基类结构,复用创建逻辑

将基类改为模板类,让派生类继承时传入自身作为模板参数,这样基类的Create()就能直接创建派生类实例。如果需要全局唯一ID,可拆分出核心类存储静态ID:

#include <memory>
#include <type_traits>

// 存储全局唯一ID的核心基类
class BaseIdCore
{
protected:
    using Id_t = int32_t;
    static Id_t CurrentId;
};

BaseIdCore::Id_t BaseIdCore::CurrentId = 0;

template<typename Derived>
class Base : public BaseIdCore
{
public:
    static std::shared_ptr<Derived> Create()
    {
        // 强制验证派生类继承关系
        static_assert(std::is_base_of_v<Base<Derived>, Derived>, 
                      "派生类必须继承自Base<Derived>");
        return std::make_shared<Derived>(CurrentId++);
    }

    Id_t GetId() const { return Id; }

protected:
    // 构造函数改为protected,仅允许派生类调用
    Base(Id_t ObjectId) : Id{ObjectId} {}

private:
    Id_t Id;
};

2. 派生类实现

派生类只需继承Base<Derived>,即可自动获得适配自身的Create()函数:

class A : public Base<A>
{
    // 可添加派生类专属成员
};

3. 使用方式

现在可以直接调用派生类的Create()方法,返回对应类型的智能指针:

int main()
{
    auto baseInst = Base<Base>::Create(); // 创建基类实例
    auto aInst = A::Create();             // 创建派生类A的实例

    // 验证ID递增逻辑
    // 输出:0、1
    std::cout << baseInst->GetId() << std::endl;
    std::cout << aInst->GetId() << std::endl;
    return 0;
}

关键说明

  • CRTP的作用:让基类感知派生类类型,避免每个派生类重复编写Create()逻辑,实现代码复用。
  • 构造函数权限:将基类构造设为protected,既保证封装性,又允许派生类调用完成初始化。
  • ID序列控制:如果需要每个派生类拥有独立的ID序列,只需将CurrentId移到模板基类Base中作为静态成员即可。

注意:你提到的A a = A::Create();无法直接实现,因为Create()返回的是std::shared_ptr<A>,不能直接赋值给栈上的A对象。正确用法是用智能指针存储实例,如auto a = A::Create();。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 22:52:39