#include class TestObject { public: TestObject() { std::cout << "Constructor" << std::endl; instanceCount += 1; } TestObject(const TestObject &other) { std::cout << "Copy constructor" << std::endl; } ~TestObject() { std::cout << "Destructor" << std::endl; instanceCount -= 1; } static void testPrint() { std::cout << "testPrint" << std::endl; } static int getInstanceCount() { return instanceCount; } private: static int instanceCount; }; int TestObject::instanceCount = 0; /// Holds unique ownership of a pointed to object and destroys it automatically template class UniquePtr { public: /// Constructor without deleter explicit UniquePtr(T *object) : object(object), deleter(nullptr) {} /// Constructor with deleter UniquePtr(T *object, void (*deleter)(T*)) : object(object), deleter(deleter) {} /// Copy constructor /// Shouldn't be used, since the pointer wouldn't be unique otherwise UniquePtr(const UniquePtr &other) = delete; /// Move constructor UniquePtr(UniquePtr &&other) : object(other.object), deleter(other.deleter) { other.object = nullptr; } /// Copy assignment operator UniquePtr &operator=(const UniquePtr &) = delete; /// Move assignment operator /// Shouldn't be used, since the pointer wouldn't be unique otherwise UniquePtr &operator=(UniquePtr &&) = delete; /// Destructor virtual ~UniquePtr() { deleteObject(); } T operator*() const { return *object; } operator bool() const { return object != nullptr; } T *operator->() const { return object; } /// Release ownership of the owned object and return the pointer to it T *Release() { T *returnObject = object; object = nullptr; return returnObject; } /// Reset the internal pointer to null void Reset() { deleteObject(); object = nullptr; } /// Swaps the currently owned object with another void Swap(T *other) { deleteObject(); object = other; } private: T *object; void (*deleter)(T*); void deleteObject() { if (deleter != nullptr && object != nullptr) { deleter(object); } else { delete object; } } }; void customTestObjectDeleter(TestObject *object) { std::cout << "Custom deleter" << std::endl; delete object; } int main() { { std::cout << "Constructing first pointer" << std::endl; UniquePtr pointer = UniquePtr(new TestObject()); std::cout << "Calling test print via pointer if it bools to true" << std::endl; if (pointer) { pointer->testPrint(); } std::cout << "Swapping for new object" << std::endl; pointer.Swap(new TestObject()); std::cout << "Move constructing new pointer" << std::endl; UniquePtr pointer2 = UniquePtr(std::move(pointer)); std::cout << "Constructing pointer with custom deleter" << std::endl; UniquePtr pointer3 = UniquePtr(new TestObject(), customTestObjectDeleter); std::cout << "Resetting that pointer" << std::endl; pointer3.Reset(); if (pointer3) { std::cout << "This shouldn't happen!" << std::endl; } } std::cout << std::endl << "All pointers should now be out of scope!" << std::endl; std::cout << TestObject::getInstanceCount() << " instances left" << std::endl; return 0; }