My unique_ptr implementationunique_ptr usage too unwieldyDeepPtr: a deep-copying unique_ptr wrapper in C++My implementation for std::unique_ptrUnique_Ptr ImplementationShared_Ptr ImplementationProtected Pointer: a unique_ptr wrapper that auto encrypts and decrypts data in memoryA C#-style Event object in C++Queue implementation using unique_ptrunique_ptr basic implementation for single objectsC++ Updated Stack Code
How to draw pentagram-like shape in Latex?
Can a generation ship withstand its own oxygen and daily wear for many thousands of years?
How to pipe results multiple results into a command?
What technology would Dwarves need to forge titanium?
Windows reverting changes made by Linux to FAT32 partion
Does the usage of mathematical symbols work differently in books than in theses?
Failing students when it might cause them economic ruin
How do I balance a campaign consisting of four kobold PCs?
Have the writers and actors of GOT responded to its poor reception?
Why would company (decision makers) wait for someone to retire, rather than lay them off, when their role is no longer needed?
How can I monitor the bulk API limit?
Appropriate liquid/solvent for life in my underground environment on Venus
How would fantasy dwarves exist, realistically?
Is it possible to determine from only a photo of a cityscape whether it was taken close with wide angle or from a distance with zoom?
how to create an executable file for an AppleScript?
FIFO data structure in pure C
Pedaling at different gear ratios on flat terrain: what's the point?
How many Dothraki are left as of Game of Thrones S8E5?
Why use a retrograde orbit?
French equivalent of the German expression "flöten gehen"
If partial derivatives of a harmonic function are constant, is the function linear?
multicol package causes underfull hbox
Would a "ring language" be possible?
Can an airline pilot be prosecuted for killing an unruly passenger who could not be physically restrained?
My unique_ptr implementation
unique_ptr usage too unwieldyDeepPtr: a deep-copying unique_ptr wrapper in C++My implementation for std::unique_ptrUnique_Ptr ImplementationShared_Ptr ImplementationProtected Pointer: a unique_ptr wrapper that auto encrypts and decrypts data in memoryA C#-style Event object in C++Queue implementation using unique_ptrunique_ptr basic implementation for single objectsC++ Updated Stack Code
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
$begingroup$
This is my simple unique_ptr implementation. Anything that could be improved upon or should be added?
#include <algorithm>
template<typename T>
class unique_ptr
private:
T * ptr_resource = nullptr;
public:
// Safely constructs resource. Operator new is called by the user. Once constructed the unique_ptr will own the resource.
// std::move is used because it is used to indicate that an object may be moved from other resource.
explicit unique_ptr(T* raw_resource) noexcept : ptr_resource(std::move(raw_resource))
unique_ptr(std::nullptr_t) : ptr_resource(nullptr)
// destroys the resource when object goes out of scope
~unique_ptr() noexcept
delete ptr_resource;
// Disables the copy/ctor and copy assignment operator. We cannot have two copies exist or it'll bypass the RAII concept.
unique_ptr(const unique_ptr<T>&) noexcept = delete;
unique_ptr& operator = (const unique_ptr&) noexcept = delete;
public:
// releases the ownership of the resource. The user is now responsible for memory clean-up.
T* release() noexcept
T* resource_ptr = this->ptr_resource;
this->ptr_resource = nullptr;
return resource_ptr;
// returns a pointer to the resource
T* get() const noexcept
return ptr_resource;
// swaps the resources
void swap(unique_ptr<T>& resource_ptr) noexcept
std::swap(ptr_resource, resource_ptr.ptr_resource);
// replaces the resource. the old one is destroyed and a new one will take it's place.
void reset(T* resource_ptr) noexcept(false)
// ensure a invalid resource is not passed or program will be terminated
if (resource_ptr == nullptr)
throw std::invalid_argument("An invalid pointer was passed, resources will not be swapped");
delete ptr_resource;
ptr_resource = nullptr;
std::swap(ptr_resource, resource_ptr);
public:
// operators
T* operator->() const noexcept
return this->ptr_resource;
T& operator*() const noexcept
return *this->ptr_resource;
// May be used to check for nullptr
;
c++ reinventing-the-wheel pointers raii
$endgroup$
add a comment |
$begingroup$
This is my simple unique_ptr implementation. Anything that could be improved upon or should be added?
#include <algorithm>
template<typename T>
class unique_ptr
private:
T * ptr_resource = nullptr;
public:
// Safely constructs resource. Operator new is called by the user. Once constructed the unique_ptr will own the resource.
// std::move is used because it is used to indicate that an object may be moved from other resource.
explicit unique_ptr(T* raw_resource) noexcept : ptr_resource(std::move(raw_resource))
unique_ptr(std::nullptr_t) : ptr_resource(nullptr)
// destroys the resource when object goes out of scope
~unique_ptr() noexcept
delete ptr_resource;
// Disables the copy/ctor and copy assignment operator. We cannot have two copies exist or it'll bypass the RAII concept.
unique_ptr(const unique_ptr<T>&) noexcept = delete;
unique_ptr& operator = (const unique_ptr&) noexcept = delete;
public:
// releases the ownership of the resource. The user is now responsible for memory clean-up.
T* release() noexcept
T* resource_ptr = this->ptr_resource;
this->ptr_resource = nullptr;
return resource_ptr;
// returns a pointer to the resource
T* get() const noexcept
return ptr_resource;
// swaps the resources
void swap(unique_ptr<T>& resource_ptr) noexcept
std::swap(ptr_resource, resource_ptr.ptr_resource);
// replaces the resource. the old one is destroyed and a new one will take it's place.
void reset(T* resource_ptr) noexcept(false)
// ensure a invalid resource is not passed or program will be terminated
if (resource_ptr == nullptr)
throw std::invalid_argument("An invalid pointer was passed, resources will not be swapped");
delete ptr_resource;
ptr_resource = nullptr;
std::swap(ptr_resource, resource_ptr);
public:
// operators
T* operator->() const noexcept
return this->ptr_resource;
T& operator*() const noexcept
return *this->ptr_resource;
// May be used to check for nullptr
;
c++ reinventing-the-wheel pointers raii
$endgroup$
$begingroup$
Please read my series on smart pointers for some help: lokiastari.com/series
$endgroup$
– Martin York
May 6 at 19:18
add a comment |
$begingroup$
This is my simple unique_ptr implementation. Anything that could be improved upon or should be added?
#include <algorithm>
template<typename T>
class unique_ptr
private:
T * ptr_resource = nullptr;
public:
// Safely constructs resource. Operator new is called by the user. Once constructed the unique_ptr will own the resource.
// std::move is used because it is used to indicate that an object may be moved from other resource.
explicit unique_ptr(T* raw_resource) noexcept : ptr_resource(std::move(raw_resource))
unique_ptr(std::nullptr_t) : ptr_resource(nullptr)
// destroys the resource when object goes out of scope
~unique_ptr() noexcept
delete ptr_resource;
// Disables the copy/ctor and copy assignment operator. We cannot have two copies exist or it'll bypass the RAII concept.
unique_ptr(const unique_ptr<T>&) noexcept = delete;
unique_ptr& operator = (const unique_ptr&) noexcept = delete;
public:
// releases the ownership of the resource. The user is now responsible for memory clean-up.
T* release() noexcept
T* resource_ptr = this->ptr_resource;
this->ptr_resource = nullptr;
return resource_ptr;
// returns a pointer to the resource
T* get() const noexcept
return ptr_resource;
// swaps the resources
void swap(unique_ptr<T>& resource_ptr) noexcept
std::swap(ptr_resource, resource_ptr.ptr_resource);
// replaces the resource. the old one is destroyed and a new one will take it's place.
void reset(T* resource_ptr) noexcept(false)
// ensure a invalid resource is not passed or program will be terminated
if (resource_ptr == nullptr)
throw std::invalid_argument("An invalid pointer was passed, resources will not be swapped");
delete ptr_resource;
ptr_resource = nullptr;
std::swap(ptr_resource, resource_ptr);
public:
// operators
T* operator->() const noexcept
return this->ptr_resource;
T& operator*() const noexcept
return *this->ptr_resource;
// May be used to check for nullptr
;
c++ reinventing-the-wheel pointers raii
$endgroup$
This is my simple unique_ptr implementation. Anything that could be improved upon or should be added?
#include <algorithm>
template<typename T>
class unique_ptr
private:
T * ptr_resource = nullptr;
public:
// Safely constructs resource. Operator new is called by the user. Once constructed the unique_ptr will own the resource.
// std::move is used because it is used to indicate that an object may be moved from other resource.
explicit unique_ptr(T* raw_resource) noexcept : ptr_resource(std::move(raw_resource))
unique_ptr(std::nullptr_t) : ptr_resource(nullptr)
// destroys the resource when object goes out of scope
~unique_ptr() noexcept
delete ptr_resource;
// Disables the copy/ctor and copy assignment operator. We cannot have two copies exist or it'll bypass the RAII concept.
unique_ptr(const unique_ptr<T>&) noexcept = delete;
unique_ptr& operator = (const unique_ptr&) noexcept = delete;
public:
// releases the ownership of the resource. The user is now responsible for memory clean-up.
T* release() noexcept
T* resource_ptr = this->ptr_resource;
this->ptr_resource = nullptr;
return resource_ptr;
// returns a pointer to the resource
T* get() const noexcept
return ptr_resource;
// swaps the resources
void swap(unique_ptr<T>& resource_ptr) noexcept
std::swap(ptr_resource, resource_ptr.ptr_resource);
// replaces the resource. the old one is destroyed and a new one will take it's place.
void reset(T* resource_ptr) noexcept(false)
// ensure a invalid resource is not passed or program will be terminated
if (resource_ptr == nullptr)
throw std::invalid_argument("An invalid pointer was passed, resources will not be swapped");
delete ptr_resource;
ptr_resource = nullptr;
std::swap(ptr_resource, resource_ptr);
public:
// operators
T* operator->() const noexcept
return this->ptr_resource;
T& operator*() const noexcept
return *this->ptr_resource;
// May be used to check for nullptr
;
c++ reinventing-the-wheel pointers raii
c++ reinventing-the-wheel pointers raii
edited May 6 at 2:59
200_success
132k20159426
132k20159426
asked May 6 at 2:56
devptrdevptr
261
261
$begingroup$
Please read my series on smart pointers for some help: lokiastari.com/series
$endgroup$
– Martin York
May 6 at 19:18
add a comment |
$begingroup$
Please read my series on smart pointers for some help: lokiastari.com/series
$endgroup$
– Martin York
May 6 at 19:18
$begingroup$
Please read my series on smart pointers for some help: lokiastari.com/series
$endgroup$
– Martin York
May 6 at 19:18
$begingroup$
Please read my series on smart pointers for some help: lokiastari.com/series
$endgroup$
– Martin York
May 6 at 19:18
add a comment |
1 Answer
1
active
oldest
votes
$begingroup$
Let me first assume that your
unique_ptr
is supposed to be movable. Then, any basic test case whould have unrevealed this:unique_ptr<int> ptr1(new int());
unique_ptr<int> ptr2 = std::move(ptr1); // Fails to compileRecall that
= delete
-ing special member functions means user-declaring them. And user-declared copy and copy assignment constructors prevent compiler-generated move (assignment) constructors! You have to manually define them. This case is by the way covered by the rule of five/C.21 Core Guidelines, and also have a look at the table posted in this SO answer for an overview of compiler-generated/-deleted/not-declared special member functions.Is the non-availability of an implicit conversion to
bool
intended? Checking if a (smart) pointer is in an empty/null state is so common in ordinary control flow statements that clients will expect this to compile:unique_ptr<SomeType> ptr = ...;
if (ptr) ... // currently fails to compileBut not that this might be debatable. Implicit conversions can cause a lot of pain, so if you intend to not allow them for the sake of a more explicit
if (ptr == nullptr) ...
that's a design decision. But one that should be documented in a comment at the top of the class.
Except the non-
explicit
-ness of the second constructor (thanks to @Deduplicator for pointing that out) taking astd::nullptr_t
, it is superfluous. You can construct an emptyunique_ptr
byunique_ptr<SomeType> emptynullptr;
which simply invokes the first constructor taking a
T*
argument. I would remove the second constructor.... and add a default constructor that initializes
ptr_resource
tonullptr
, asunique_tr<SomeType> empty;
might be a way of constructing an empty smart pointer that users would expect to compile.
Move-constructing the
ptr_resource
in the constructor initializer byptr_resource(std::move(raw_resource))
doesn't make much sense. Just copy the pointer instead. The comment// std::move is used because it is used to indicate that an object may be moved from other resource.
is rather confusing, becauseT* raw_resource
is already a pointer, and hence a handle to a resource, not the resource itself.The
release
member function can be implemented more conveniently asT* release() noexcept
return std::exchange(ptr_resource, nullptr);I wouln't let the
reset
member function throw when the input is anullptr
. Why shouldn't it be allowed toreset
aunique_ptr
with anullptr
, turning it back into an empty state?The only facilities you use from the standard library are
std::move
andstd::swap
. Those are in<utility>
, so you don't need to include<algorithm>
, which is probably much heavier in terms of compile times.I would omit the
this->
prefix, it's unnecessarily verbose. But that might be a matter of taste.Have you considered custom deleters? This makes the class template more reusable in scenarios other than pointers to heap resources, e.g. closing a file upon destruction etc.
$endgroup$
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f219783%2fmy-unique-ptr-implementation%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
Let me first assume that your
unique_ptr
is supposed to be movable. Then, any basic test case whould have unrevealed this:unique_ptr<int> ptr1(new int());
unique_ptr<int> ptr2 = std::move(ptr1); // Fails to compileRecall that
= delete
-ing special member functions means user-declaring them. And user-declared copy and copy assignment constructors prevent compiler-generated move (assignment) constructors! You have to manually define them. This case is by the way covered by the rule of five/C.21 Core Guidelines, and also have a look at the table posted in this SO answer for an overview of compiler-generated/-deleted/not-declared special member functions.Is the non-availability of an implicit conversion to
bool
intended? Checking if a (smart) pointer is in an empty/null state is so common in ordinary control flow statements that clients will expect this to compile:unique_ptr<SomeType> ptr = ...;
if (ptr) ... // currently fails to compileBut not that this might be debatable. Implicit conversions can cause a lot of pain, so if you intend to not allow them for the sake of a more explicit
if (ptr == nullptr) ...
that's a design decision. But one that should be documented in a comment at the top of the class.
Except the non-
explicit
-ness of the second constructor (thanks to @Deduplicator for pointing that out) taking astd::nullptr_t
, it is superfluous. You can construct an emptyunique_ptr
byunique_ptr<SomeType> emptynullptr;
which simply invokes the first constructor taking a
T*
argument. I would remove the second constructor.... and add a default constructor that initializes
ptr_resource
tonullptr
, asunique_tr<SomeType> empty;
might be a way of constructing an empty smart pointer that users would expect to compile.
Move-constructing the
ptr_resource
in the constructor initializer byptr_resource(std::move(raw_resource))
doesn't make much sense. Just copy the pointer instead. The comment// std::move is used because it is used to indicate that an object may be moved from other resource.
is rather confusing, becauseT* raw_resource
is already a pointer, and hence a handle to a resource, not the resource itself.The
release
member function can be implemented more conveniently asT* release() noexcept
return std::exchange(ptr_resource, nullptr);I wouln't let the
reset
member function throw when the input is anullptr
. Why shouldn't it be allowed toreset
aunique_ptr
with anullptr
, turning it back into an empty state?The only facilities you use from the standard library are
std::move
andstd::swap
. Those are in<utility>
, so you don't need to include<algorithm>
, which is probably much heavier in terms of compile times.I would omit the
this->
prefix, it's unnecessarily verbose. But that might be a matter of taste.Have you considered custom deleters? This makes the class template more reusable in scenarios other than pointers to heap resources, e.g. closing a file upon destruction etc.
$endgroup$
add a comment |
$begingroup$
Let me first assume that your
unique_ptr
is supposed to be movable. Then, any basic test case whould have unrevealed this:unique_ptr<int> ptr1(new int());
unique_ptr<int> ptr2 = std::move(ptr1); // Fails to compileRecall that
= delete
-ing special member functions means user-declaring them. And user-declared copy and copy assignment constructors prevent compiler-generated move (assignment) constructors! You have to manually define them. This case is by the way covered by the rule of five/C.21 Core Guidelines, and also have a look at the table posted in this SO answer for an overview of compiler-generated/-deleted/not-declared special member functions.Is the non-availability of an implicit conversion to
bool
intended? Checking if a (smart) pointer is in an empty/null state is so common in ordinary control flow statements that clients will expect this to compile:unique_ptr<SomeType> ptr = ...;
if (ptr) ... // currently fails to compileBut not that this might be debatable. Implicit conversions can cause a lot of pain, so if you intend to not allow them for the sake of a more explicit
if (ptr == nullptr) ...
that's a design decision. But one that should be documented in a comment at the top of the class.
Except the non-
explicit
-ness of the second constructor (thanks to @Deduplicator for pointing that out) taking astd::nullptr_t
, it is superfluous. You can construct an emptyunique_ptr
byunique_ptr<SomeType> emptynullptr;
which simply invokes the first constructor taking a
T*
argument. I would remove the second constructor.... and add a default constructor that initializes
ptr_resource
tonullptr
, asunique_tr<SomeType> empty;
might be a way of constructing an empty smart pointer that users would expect to compile.
Move-constructing the
ptr_resource
in the constructor initializer byptr_resource(std::move(raw_resource))
doesn't make much sense. Just copy the pointer instead. The comment// std::move is used because it is used to indicate that an object may be moved from other resource.
is rather confusing, becauseT* raw_resource
is already a pointer, and hence a handle to a resource, not the resource itself.The
release
member function can be implemented more conveniently asT* release() noexcept
return std::exchange(ptr_resource, nullptr);I wouln't let the
reset
member function throw when the input is anullptr
. Why shouldn't it be allowed toreset
aunique_ptr
with anullptr
, turning it back into an empty state?The only facilities you use from the standard library are
std::move
andstd::swap
. Those are in<utility>
, so you don't need to include<algorithm>
, which is probably much heavier in terms of compile times.I would omit the
this->
prefix, it's unnecessarily verbose. But that might be a matter of taste.Have you considered custom deleters? This makes the class template more reusable in scenarios other than pointers to heap resources, e.g. closing a file upon destruction etc.
$endgroup$
add a comment |
$begingroup$
Let me first assume that your
unique_ptr
is supposed to be movable. Then, any basic test case whould have unrevealed this:unique_ptr<int> ptr1(new int());
unique_ptr<int> ptr2 = std::move(ptr1); // Fails to compileRecall that
= delete
-ing special member functions means user-declaring them. And user-declared copy and copy assignment constructors prevent compiler-generated move (assignment) constructors! You have to manually define them. This case is by the way covered by the rule of five/C.21 Core Guidelines, and also have a look at the table posted in this SO answer for an overview of compiler-generated/-deleted/not-declared special member functions.Is the non-availability of an implicit conversion to
bool
intended? Checking if a (smart) pointer is in an empty/null state is so common in ordinary control flow statements that clients will expect this to compile:unique_ptr<SomeType> ptr = ...;
if (ptr) ... // currently fails to compileBut not that this might be debatable. Implicit conversions can cause a lot of pain, so if you intend to not allow them for the sake of a more explicit
if (ptr == nullptr) ...
that's a design decision. But one that should be documented in a comment at the top of the class.
Except the non-
explicit
-ness of the second constructor (thanks to @Deduplicator for pointing that out) taking astd::nullptr_t
, it is superfluous. You can construct an emptyunique_ptr
byunique_ptr<SomeType> emptynullptr;
which simply invokes the first constructor taking a
T*
argument. I would remove the second constructor.... and add a default constructor that initializes
ptr_resource
tonullptr
, asunique_tr<SomeType> empty;
might be a way of constructing an empty smart pointer that users would expect to compile.
Move-constructing the
ptr_resource
in the constructor initializer byptr_resource(std::move(raw_resource))
doesn't make much sense. Just copy the pointer instead. The comment// std::move is used because it is used to indicate that an object may be moved from other resource.
is rather confusing, becauseT* raw_resource
is already a pointer, and hence a handle to a resource, not the resource itself.The
release
member function can be implemented more conveniently asT* release() noexcept
return std::exchange(ptr_resource, nullptr);I wouln't let the
reset
member function throw when the input is anullptr
. Why shouldn't it be allowed toreset
aunique_ptr
with anullptr
, turning it back into an empty state?The only facilities you use from the standard library are
std::move
andstd::swap
. Those are in<utility>
, so you don't need to include<algorithm>
, which is probably much heavier in terms of compile times.I would omit the
this->
prefix, it's unnecessarily verbose. But that might be a matter of taste.Have you considered custom deleters? This makes the class template more reusable in scenarios other than pointers to heap resources, e.g. closing a file upon destruction etc.
$endgroup$
Let me first assume that your
unique_ptr
is supposed to be movable. Then, any basic test case whould have unrevealed this:unique_ptr<int> ptr1(new int());
unique_ptr<int> ptr2 = std::move(ptr1); // Fails to compileRecall that
= delete
-ing special member functions means user-declaring them. And user-declared copy and copy assignment constructors prevent compiler-generated move (assignment) constructors! You have to manually define them. This case is by the way covered by the rule of five/C.21 Core Guidelines, and also have a look at the table posted in this SO answer for an overview of compiler-generated/-deleted/not-declared special member functions.Is the non-availability of an implicit conversion to
bool
intended? Checking if a (smart) pointer is in an empty/null state is so common in ordinary control flow statements that clients will expect this to compile:unique_ptr<SomeType> ptr = ...;
if (ptr) ... // currently fails to compileBut not that this might be debatable. Implicit conversions can cause a lot of pain, so if you intend to not allow them for the sake of a more explicit
if (ptr == nullptr) ...
that's a design decision. But one that should be documented in a comment at the top of the class.
Except the non-
explicit
-ness of the second constructor (thanks to @Deduplicator for pointing that out) taking astd::nullptr_t
, it is superfluous. You can construct an emptyunique_ptr
byunique_ptr<SomeType> emptynullptr;
which simply invokes the first constructor taking a
T*
argument. I would remove the second constructor.... and add a default constructor that initializes
ptr_resource
tonullptr
, asunique_tr<SomeType> empty;
might be a way of constructing an empty smart pointer that users would expect to compile.
Move-constructing the
ptr_resource
in the constructor initializer byptr_resource(std::move(raw_resource))
doesn't make much sense. Just copy the pointer instead. The comment// std::move is used because it is used to indicate that an object may be moved from other resource.
is rather confusing, becauseT* raw_resource
is already a pointer, and hence a handle to a resource, not the resource itself.The
release
member function can be implemented more conveniently asT* release() noexcept
return std::exchange(ptr_resource, nullptr);I wouln't let the
reset
member function throw when the input is anullptr
. Why shouldn't it be allowed toreset
aunique_ptr
with anullptr
, turning it back into an empty state?The only facilities you use from the standard library are
std::move
andstd::swap
. Those are in<utility>
, so you don't need to include<algorithm>
, which is probably much heavier in terms of compile times.I would omit the
this->
prefix, it's unnecessarily verbose. But that might be a matter of taste.Have you considered custom deleters? This makes the class template more reusable in scenarios other than pointers to heap resources, e.g. closing a file upon destruction etc.
edited May 6 at 9:30
answered May 6 at 7:15
lubgrlubgr
9289
9289
add a comment |
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f219783%2fmy-unique-ptr-implementation%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
$begingroup$
Please read my series on smart pointers for some help: lokiastari.com/series
$endgroup$
– Martin York
May 6 at 19:18