This question要求以简洁的方式在 C++ 中实现静态工厂方法,this answer描述了一种明确的方法。返回值优化将使我们免于制作不必要的 Object
拷贝,从而使这种创建 Object
的方式与直接调用构造函数一样高效。在私有(private)构造函数中将 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
定义一个复制构造函数。
在这种情况下,什么是实现这种模式的类似干净但有效的方法?
为了预测关于为什么这是相关的可能问题,我考虑让构造函数具有比仅仅复制参数更复杂的逻辑作为反模式。我希望构造函数:
- 保证工作正常,不抛出异常,
- 不要在后台进行繁重的计算。
因此,我更喜欢将复杂的初始化逻辑放入静态方法中。此外,这种方法提供了额外的好处,例如即使输入参数类型相同,也可以通过静态工厂方法名称进行重载,并且可以清楚地以方法名称说明内部正在执行的操作。
最佳答案
感谢移动构造函数,您可能会这样做:
class Object {
Foo foo;
explicit Object(Foo&& foo_) : foo(std::move(foo_)) {}
public:
static Object FromFooArg(const FooArg& fooArg) {
// Create foo using fooArg here
Foo foo = ...
return Object(std::move(foo));
}
};
如果 Foo
不可移动,则可以将其包装在智能指针中:
class Object {
std::unique_ptr<Foo> foo;
explicit Object(std::unique_ptr<Foo>&& foo_) : foo(std::move(foo_)) {}
public:
static Object FromFooArg(const FooArg& fooArg) {
// Create foo using fooArg here
std::unique_ptr<Foo> foo = ...
return Object(std::move(foo));
}
};
关于C++ 静态工厂方法与构造函数 : how to avoid copying?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50941946/