是否有 C++ 中首选的构建器模式的替代方案?

Is there an alternative to the builder pattern that is preferred in C++?

我来自 Java,那里大量使用构建器模式,例如

Foo foo = new FooBuilder()
    .setBar(43)
    .setBaz("hello, world!")
    .enableCache(true)
    .build();

例如,Automapper 是一个流行的库,它通过 Java 注释生成此模式。

我没有看到任何这样的 C++ 库——只有在线的要点和博客文章以及示例临时实现。

缺少库是否意味着构建器模式在 C++ 中不是首选?那么替代或首选成语是什么?

也许它有助于描述我真正想要的东西。我喜欢构建器模式为我提供的语法,例如,如果我可以设置 20 个字段(例如 一个大型配置),但可能只设置 4 个或可能设置全部 20 个,而无需必须为每种情况创建显式构造函数。

一个常见的模式是聚合初始化:

Foo foo = {
    .bar=43,
    .baz="hello, world!",
    .enableCache=true,
};

请注意,此处使用的指定初始化程序是在 C++20 中引入的。在此之前,您只能按位置初始化子对象。

另一种在没有指定初始化器的情况下很常见的模式是值初始化,然后是数据成员赋值:

Foo foo = {};
foo.bar = 43;
foo.baz = "hello, world!";
foo.enableCache = true;

两种模式的使用都不需要使用库。

您只需修正类型错误:

Foo foo = (*new FooBuilder())
    .setBar(43)
    .setBaz("hello, world!")
    .enableCache(true)
    .build();

剩下的就是将您的函数正确定义为始终 return FooBuilder&(构建 returns a Foo 除外)。

假设 FooBuilder 是从各种来源积累选项的东西,而不仅仅是分配成员变量。如果您的代码真的很像您创建构建器的示例,请分配所有选项并构建 Foo 然后只需使用构造函数或聚合初始化:

Foo foo = {
    .bar=43,
    .baz="hello, world!",
    .enableCache=true,
};

更新:这是我在保留 new 时想到的用例:

FooBuilder *builer = nullptr;
if (use_bla_builder) {
    builder = new Bla::FooBuilder();
} else {
    builder = new Blub::FooBuilder();
}
Foo foo = (*builder)
    .setBar(43)
    .setBaz("hello, world!")
    .enableCache(true)
    .build();
delete builder;

注意:构建器是抽象的,而它构建的 Foo 是具体的。

如果这是您的代码,您可以通过设置来近似它 return *如下所示:

class Foo {
public:
     Foo & setter1(int value) { ...; return *this; }
     Foo & setter2(int value) { ...; return *this; }
};

Foo foo;
foo.setter1(1)
   .setter2(2);

或者指针或者智能指针,或者其他什么。我开始这样做是因为它使代码更简洁。显然,如果您的构造函数做了很多,那么您仍然在做很多。如果 Foo 是一个 subclass,并且你的一些 setter 调用在基础 class 上,你也会遇到问题,因为突然间你没有 Foo return ]ed,而是一个 BaseFoo。

所以它并不完美。

我见过 self-implemented 构建器模式,它们实际上是一个合适的构建器,但坦率地说,我认为这是零收益的大量开销。