我想在现代C ++中实现一个生成器模式。来自Java背景,这是我想模仿的东西:
// Usage
FooBuilder builder;
builder.setArg1(a);
builder.setArg2(b);
Foo foo = builder.build();
// Implementation
public class FooBuilder {
// ...
public Foo build() {
return new Foo(a, b);
}
}
典型的较旧的教科书只是建议人们这样做,就像在C ++中那样:
class FooBuilder {
// ...
Foo* build() {
return new Foo(m_a, m_b);
}
}
这显然不是一个好主意,因为处理原始指针可能容易出错。到目前为止,我想到的最好的方法是std::unique_ptr
手动使用:
class FooBuilder {
// ...
std::unique_ptr<Foo> build() {
return std::make_unique<Foo>(m_a, m_b);
}
}
// Usage
auto fooPtr = builder.build();
Foo& foo = *fooPtr;
foo.someMethod();
更好,因为它不需要手动delete
,这种两层转换为引用是很丑陋的,而且更重要的是,它使用堆分配,而简单的无生成器版本只需要简单的堆栈分配就可以了:
Foo foo(..., ...); // <= on stack
有没有更好的方法可以做到这一点,即没有unique_ptr或为Foo提供某种堆栈上的分配?
通常,如果Foo是copy_constructible,则可以按值返回Foo。
#include <type_traits>
class Foo
{
int i;
public:
Foo(int i): i(i){}
};
static_assert(std::is_copy_constructible<Foo>::value, "Foo is copy-constructible");
struct FooFactory
{
//...
Foo build() {return Foo(1);}
};
int main()
{
FooFactory factory;
//...
Foo foo = factory.build();
}
c ++ 17中的新增功能保证了copy elision,这意味着即使类型没有复制或移动构造函数,您也可以按值返回:
#include <type_traits>
class Foo
{
int i;
public:
Foo(int i): i(i){}
// regular copy constructors don't exist for whatever reason.
Foo() = delete;
Foo(Foo const& ) =delete;
Foo(Foo&& ) = delete;
Foo& operator=(Foo const&) = delete;
Foo& operator=(Foo&& ) = delete;
};
static_assert(not std::is_copy_constructible<Foo>::value, "Foo is definitely not copy-constructible");
struct FooFactory
{
//...
Foo build() {return Foo(1);}
};
int main()
{
FooFactory factory;
//...
Foo foo = factory.build();
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句