Modern C ++ builder pattern without unique_ptr

I would like to implement a builder pattern in modern C ++. Based on the Java background, this is what I would 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 old tutorials are simply advised to do this as in C ++:

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

which is obviously not a good idea, as working with raw pointers can be error prone. The best I have used so far is to use it std::unique_ptrmanually:

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

This is better since it doesn't require manual delete, this two-line conversion to a link is ugly, and more importantly, it uses heap allocation, while a simple version without a linker will be completely fine with just a simple stack distribution:

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

, unique_ptr - Foo?

+4
2

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

++ 17, 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();
}
+4

, . build() Foo :

class FooBuilder {
public:
    Foo build() { // You may consider having a &&-qualified overload
        return Foo{ ..., ... };
    }
};
+5

Source: https://habr.com/ru/post/1692936/


All Articles