Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modern C++ builder pattern without unique_ptr

Tags:

c++

builder

I'd want to implement a builder pattern in modern C++. Coming from Java background, this is something I'd like to emulate:

// 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);
    }
}

Typical older textbooks just advice one to do it like that in C++:

class FooBuilder {
    // ...
    Foo* build() {
        return new Foo(m_a, m_b);
    }
}

which is obviously not a good idea, as dealing with raw pointers might be error-prone. The best I've came up with so far is using std::unique_ptr manually:

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();

It's better, as it doesn't require manual delete, this two-liner conversion to reference is ugly, and, what's more important, it uses heap allocation, while simple builder-less version would be totally ok with just a simple stack allocation:

Foo foo(..., ...); // <= on stack

Are there any better ways to do that, i.e. without unique_ptr, or with some sort of on-stack allocation for Foo?

like image 586
GreyCat Avatar asked Jan 02 '23 21:01

GreyCat


1 Answers

There's no reason why you have to allocate on the heap to use the builder pattern. Just have your build() method return Foo directly:

class FooBuilder {
public:
    Foo build() { // You may consider having a &&-qualified overload
        return Foo{ ..., ... };
    }
};
like image 194
Justin Avatar answered Jan 15 '23 11:01

Justin