Last active
May 8, 2021 00:42
-
-
Save SanderMertens/6a5499db5fd7652a8d7e8551785d9f9f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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