Last active
April 26, 2020 08:36
-
-
Save dwilliamson/2cbdeb0a57a937dc44909f76fc3f0a4e to your computer and use it in GitHub Desktop.
Scoped (unique) "smart" pointer, deleting the pointer on destruction. Doesn't wrap the unique pointer in accessor functions, instead requiring explicit dereferencing and a const pointer that can't (shouldn't) be modified externally.
This file contains 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
template <typename Type> | |
struct uptr | |
{ | |
uptr() = default; | |
uptr(Type* ptr) | |
: ptr(ptr) | |
{ | |
} | |
~uptr() | |
{ | |
delete ptr; | |
} | |
// Take ownership of a raw pointer | |
uptr& operator = (Type* in_ptr) | |
{ | |
assert(ptr == nullptr); | |
// Cast away constness for assignments. Not ideal but the language is limited, here. | |
const_cast<Type*&>(ptr) = in_ptr; | |
return *this; | |
} | |
// Non copyable | |
uptr(const uptr&) = delete; | |
uptr& operator = (const uptr&) = delete; | |
// Move constructable, for return values | |
uptr(uptr&& rhs) | |
: ptr(rhs.ptr) | |
{ | |
} | |
// Disable move assignment, for now | |
uptr& operator = (uptr&&) = delete; | |
// Variable itself is const to discourage users from modifying it. It's public and not wrapped by | |
// method access to prevent a tonne of generated code in debug and pointless stepping in/out of | |
// functions when retrieving the pointer. | |
Type* const ptr = nullptr; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Omitted value assignment in favor of move assignment. Constructors are permitted to mutate const members, do placement new is used to reconstruct instead of const_cast. Safer because move constructor always invalidates the source to avoid double deletion in cases such as:
uptr<foo> a = new foo(); uptr<foo> b = std::move(a);