Skip to content

Instantly share code, notes, and snippets.

@SanderMertens
Last active May 8, 2021 00:42
Show Gist options
  • Select an option

  • Save SanderMertens/6a5499db5fd7652a8d7e8551785d9f9f to your computer and use it in GitHub Desktop.

Select an option

Save SanderMertens/6a5499db5fd7652a8d7e8551785d9f9f to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <memory>
struct BuilderCtor { };
template<typename T>
struct Delay {
explicit Delay() : obj_(T()) { printf("Delay::ctor()\n"); }
~Delay() {
obj_.build();
printf("Delay::dtor()\n");
}
T& get() { return obj_; }
T obj_;
};
class Object {
public:
// Dummy constructor that doesn't actually construct the object
explicit Object(BuilderCtor t) { printf("Object[%p]::builder ctor\n", this); }
// Actual constructor
explicit Object(int value) : value_(value) { printf("Object[%p]::ctor(%d)\n", this, value); }
~Object() { printf("Object[%p]::dtor\n", this); delete alloc_val; }
Object(const Object& obj) {
delete this->alloc_val;
this->alloc_val = new int(*obj.alloc_val);
}
Object(Object&& obj) {
delete this->alloc_val;
this->alloc_val = obj.alloc_val;
obj.alloc_val = nullptr;
}
int value_ = 0;
bool built_ = false;
int *alloc_val = new int(10);
};
class ObjectBuilder : public Object {
public:
explicit ObjectBuilder() : Object(BuilderCtor()) {
build_param_ = 0;
printf("ObjectBuilder[%p]::ctor()\n", this);
target_ = this;
}
~ObjectBuilder() {
printf("ObjectBuilder[%p]::dtor()\n", this);
}
ObjectBuilder(const ObjectBuilder& obj) : Object(obj) {
printf("ObjectBuilder::copy ctor (%p -> %p)\n", &obj, this);
*this = obj;
}
ObjectBuilder(ObjectBuilder&& obj) : Object(std::move(obj)) {
printf("ObjectBuilder::move ctor (%p -> %p)\n", &obj, this);
*this = std::move(obj);
}
ObjectBuilder& operator=(const ObjectBuilder& obj) {
printf("ObjectBuilder::copy= (%p -> %p)\n", &obj, this);
value_ = obj.value_;
build_param_ = obj.build_param_;
return *this;
}
ObjectBuilder& operator=(ObjectBuilder&& obj) {
printf("ObjectBuilder::move= (%p -> %p)\n", &obj, this);
value_ = obj.value_;
build_param_ = obj.build_param_;
obj.target_ = this;
this->target_ = this;
return *this;
}
ObjectBuilder&& add() {
printf("ObjectBuilder::add()\n");
build_param_ += 1;
return std::move(*this);
}
void build() {
if (target_ != this) {
printf("ObjectBuilder[%p]::forward build()\n", this);
target_->build();
} else {
printf("ObjectBuilder[%p]::build()\n", this);
this->~Object();
new(this) Object(build_param_);
built_ = true;
}
}
const char *name_;
ObjectBuilder* target_;
private:
int build_param_;
};
class Factory {
public:
ObjectBuilder&& create(Delay<ObjectBuilder> t = Delay<ObjectBuilder>()) {
return std::move(t.get());
}
};
int main(int argc, char *argv[]) {
Factory f;
printf("\nobj create\n");
auto obj_1 = f.create();
printf("nobj created (%d, built = %d)\n", obj_1.value_, obj_1.built_);
printf("\nobj create\n");
auto obj_2 = f.create().add().add().add();
printf("obj created (%d, built = %d)\n", obj_2.value_, obj_2.built_);
printf("\n");
// object dtors will be printed after this
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment