参考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
相关产品推荐
相关产品推荐

