我想在现代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);
}
}
Run Code Online (Sandbox Code Playgroud)
典型的旧教科书只是建议一个人在C++中这样做:
class FooBuilder {
// ...
Foo* build() {
return new Foo(m_a, m_b);
}
}
Run Code Online (Sandbox Code Playgroud)
这显然不是一个好主意,因为处理原始指针可能容易出错.到目前为止我提出的最好的是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();
Run Code Online (Sandbox Code Playgroud)
它更好,因为它不需要手动delete,这个双线程转换为参考是丑陋的,更重要的是,它使用堆分配,而简单的无构建器版本只需一个简单的堆栈分配就完全没问题:
Foo foo(..., ...); // <= on stack
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法来做到这一点,即没有unique_ptr,或者为Foo进行某种堆栈分配?
没有理由必须在堆上分配以使用构建器模式.只需直接build()返回您的方法Foo:
class FooBuilder {
public:
Foo build() { // You may consider having a &&-qualified overload
return Foo{ ..., ... };
}
};
Run Code Online (Sandbox Code Playgroud)
一般来说,如果 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();
}
Run Code Online (Sandbox Code Playgroud)
c++17 中的 new保证复制省略,这意味着即使类型没有复制或移动构造函数,您也可以按值返回:
#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();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
548 次 |
| 最近记录: |