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

参考Java实现,如何在C++中实现CRTP风格的流畅接口Builder模式?

没问题!我来帮你把Java里这套带流畅接口的Builder继承结构,转换成C++版本——而且用CRTP(奇异递归模板模式)来实现和Java里self()一样的类型推导效果,完美适配流畅调用的需求。

先回顾下你提供的Java实现(方便对照):

// Base class
public abstract class BaseClass {
    private final int base_class_variable;

    BaseClass(final Builder<?> builder) {
        this.base_class_variable = builder.base_class_variable;
    }

    public abstract static class Builder<B extends Builder> {
        int base_class_variable;

        public B setBaseClassVariable(final int variable) {
            this.base_class_variable = variable;
            return self();
        }

        protected abstract B self();
    }
}

// Derived class
public final class DerivedClass extends BaseClass {
    private final int derived_class_variable;

    private DerivedClass(final Builder builder) {
        super(builder);
        this.derived_class_variable = builder.derived_class_variable;
    }

    public static Builder builder() {
        return new Builder();
    }

    public static final class Builder extends BaseClass.Builder<Builder> {
        private int derived_class_variable;

        public Builder setDerivedClassVariable(final int variable) {
            this.derived_class_variable = variable;
            return self();
        }

        public DerivedClass build() {
            return new DerivedClass(this);
        }

        @Override
        protected Builder self() {
            return this;
        }
    }
}

// Creating an instance of DerivedClass
DerivedClass dInstance = DerivedClass.builder()
        .setBaseClassVariable(5)
        .setDerivedClassVariable(10)
        .build();

接下来是对应的C++实现,核心用CRTP替代Java的泛型约束,实现静态类型安全的流畅接口:

C++版本实现(带CRTP的流畅Builder模式)

1. 基类与CRTP Builder基类

基类的Builder用模板参数指定派生Builder类型,通过self()静态转换返回派生类型,实现链式调用:

#include <iostream>

// 基类
class BaseClass {
protected:
    // 保护构造,仅派生类可调用
    explicit BaseClass(int base_var) : base_class_variable(base_var) {}

public:
    // CRTP Builder基类:DerivedBuilder是继承该类的派生Builder类型
    template<typename DerivedBuilder>
    class Builder {
    protected:
        int base_class_variable = 0; // 默认初始化

        // 返回派生Builder的引用,实现流畅接口的类型衔接
        DerivedBuilder& self() {
            return static_cast<DerivedBuilder&>(*this);
        }

    public:
        // 设置基类变量,返回派生Builder类型
        DerivedBuilder& setBaseClassVariable(int variable) {
            base_class_variable = variable;
            return self();
        }
    };

    // 基类成员方法示例
    int getBaseVariable() const {
        return base_class_variable;
    }

private:
    int base_class_variable;
};

2. 派生类与派生Builder

派生Builder继承自BaseClass::Builder<DerivedClass::Builder>,扩展自己的设置方法,最终实现build()创建实例:

// 派生类
class DerivedClass : public BaseClass {
    // 私有构造,仅Builder可创建实例
    explicit DerivedClass(int base_var, int derived_var)
        : BaseClass(base_var), derived_class_variable(derived_var) {}

public:
    // 派生类Builder,继承基类的CRTP Builder
    class Builder : public BaseClass::Builder<Builder> {
    private:
        int derived_class_variable = 0;

    public:
        // 设置派生类变量,返回当前Builder引用
        Builder& setDerivedClassVariable(int variable) {
            derived_class_variable = variable;
            return *this;
        }

        // 构建DerivedClass实例
        DerivedClass build() {
            return DerivedClass(this->base_class_variable, derived_class_variable);
        }
    };

    // 派生类成员方法示例
    int getDerivedVariable() const {
        return derived_class_variable;
    }

private:
    int derived_class_variable;
};

3. 使用示例

和Java的调用方式几乎完全一致,链式调用非常流畅:

int main() {
    DerivedClass dInstance = DerivedClass::Builder()
        .setBaseClassVariable(5)
        .setDerivedClassVariable(10)
        .build();

    std::cout << "Base variable: " << dInstance.getBaseVariable() << std::endl;
    std::cout << "Derived variable: " << dInstance.getDerivedVariable() << std::endl;

    return 0;
}

运行输出:

Base variable: 5
Derived variable: 10

核心细节说明

  • CRTP替代Java泛型:C++没有Java那样的泛型约束,用CRTP实现静态多态,既保证了类型安全,又避免了虚函数的性能开销。
  • 访问控制对齐:基类构造设为protected,派生类构造设为private,确保只能通过Builder创建实例,和Java的封装逻辑一致。
  • 流畅接口实现:所有设置方法都返回对应Builder的引用,基类通过self()转换为派生类型,派生类直接返回*this,完美支持任意顺序的链式调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:08:57