这个问题询问在C++中实现静态工厂方法的清晰方式,而这个答案描述了一种明确的方法。返回值优化将使我们避免复制Object
,因此创建Object
的这种方式就像直接调用构造函数一样有效率。在私有构造函数中将i
复制到id
的开销可以忽略不计,因为它是一个小的int
。
然而,这个问题和答案并没有涵盖更复杂的情况,即Object
包含一个类Foo
的实例变量(需要复杂的初始化逻辑)而不是一个小的原始类型。假设我想使用传递给Object
的参数构造Foo
。使用构造函数的解决方案会看起来像:
class Object {
Foo foo;
public:
Object(const FooArg& fooArg) {
// Create foo using fooArg here
foo = ...
}
}
我认为一个类似于引用答案的静态工厂方法的替代方案是:
class Object {
Foo foo;
explicit Object(const Foo& foo_):
foo(foo_)
{
}
public:
static Object FromFooArg(const FooArg& fooArg) {
// Create foo using fooArg here
Foo foo = ...
return Object(foo);
}
}
在这种情况下,复制 foo_
到 foo
的开销不再无关紧要,因为 Foo
可能是一个任意复杂的类。此外,据我所知(作为 C++ 新手,可能我错了),这个代码隐式地要求定义 Foo
的复制构造函数。
有没有一种同样简洁但也有效的方法来实现这种模式?
为了预先考虑可能出现的关于为什么这很重要的问题,我认为具有比只复制参数更复杂逻辑的构造函数是一种反模式。 我期望构造函数:
- 保证工作并且不抛出异常,
- 并且在内部不进行重计算。
因此,我更喜欢将复杂的初始化逻辑放入静态方法中。此外,这种方法提供了额外的好处,例如通过静态工厂方法名称进行重载,即使输入参数类型相同,以及可以清楚地说明方法名称中正在执行的操作。
foo
(我假设所有的初始化都是昂贵的),然后你创建了另一个Foo
对象,并将其分配给默认构造的对象。 - StoryTeller - Unslander Monicafoo = Foo(fooArg)
,那么只有该构造函数被调用,不会发生任何复制。我从Java跳入C++的知识非常浅薄。无论如何,我的主要关注点是_复制_而不是_初始化_(即使对于可能很大的对象,例如空数组初始化,初始化也可能很便宜)。 - VosslerfooArg
初始化其foo
的构造函数有什么问题吗?这样的构造函数当然也可以被工厂使用。 - Walter