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;








5












$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
;









share|improve this question











$endgroup$











  • $begingroup$
    Please read my series on smart pointers for some help: lokiastari.com/series
    $endgroup$
    – Martin York
    May 6 at 19:18

















5












$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
;









share|improve this question











$endgroup$











  • $begingroup$
    Please read my series on smart pointers for some help: lokiastari.com/series
    $endgroup$
    – Martin York
    May 6 at 19:18













5












5








5


1



$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
;









share|improve this question











$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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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
















  • $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










1 Answer
1






active

oldest

votes


















6












$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 compile


    Recall 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 compile


    But 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 a std::nullptr_t, it is superfluous. You can construct an empty unique_ptr by



    unique_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 to nullptr, as



    unique_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 by ptr_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, because T* 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 as



    T* release() noexcept

    return std::exchange(ptr_resource, nullptr);



  • I wouln't let the reset member function throw when the input is a nullptr. Why shouldn't it be allowed to reset a unique_ptr with a nullptr, turning it back into an empty state?


  • The only facilities you use from the standard library are std::move and std::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.






share|improve this answer











$endgroup$













    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
    );



    );













    draft saved

    draft discarded


















    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









    6












    $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 compile


      Recall 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 compile


      But 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 a std::nullptr_t, it is superfluous. You can construct an empty unique_ptr by



      unique_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 to nullptr, as



      unique_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 by ptr_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, because T* 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 as



      T* release() noexcept

      return std::exchange(ptr_resource, nullptr);



    • I wouln't let the reset member function throw when the input is a nullptr. Why shouldn't it be allowed to reset a unique_ptr with a nullptr, turning it back into an empty state?


    • The only facilities you use from the standard library are std::move and std::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.






    share|improve this answer











    $endgroup$

















      6












      $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 compile


        Recall 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 compile


        But 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 a std::nullptr_t, it is superfluous. You can construct an empty unique_ptr by



        unique_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 to nullptr, as



        unique_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 by ptr_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, because T* 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 as



        T* release() noexcept

        return std::exchange(ptr_resource, nullptr);



      • I wouln't let the reset member function throw when the input is a nullptr. Why shouldn't it be allowed to reset a unique_ptr with a nullptr, turning it back into an empty state?


      • The only facilities you use from the standard library are std::move and std::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.






      share|improve this answer











      $endgroup$















        6












        6








        6





        $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 compile


          Recall 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 compile


          But 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 a std::nullptr_t, it is superfluous. You can construct an empty unique_ptr by



          unique_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 to nullptr, as



          unique_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 by ptr_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, because T* 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 as



          T* release() noexcept

          return std::exchange(ptr_resource, nullptr);



        • I wouln't let the reset member function throw when the input is a nullptr. Why shouldn't it be allowed to reset a unique_ptr with a nullptr, turning it back into an empty state?


        • The only facilities you use from the standard library are std::move and std::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.






        share|improve this answer











        $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 compile


          Recall 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 compile


          But 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 a std::nullptr_t, it is superfluous. You can construct an empty unique_ptr by



          unique_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 to nullptr, as



          unique_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 by ptr_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, because T* 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 as



          T* release() noexcept

          return std::exchange(ptr_resource, nullptr);



        • I wouln't let the reset member function throw when the input is a nullptr. Why shouldn't it be allowed to reset a unique_ptr with a nullptr, turning it back into an empty state?


        • The only facilities you use from the standard library are std::move and std::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.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited May 6 at 9:30

























        answered May 6 at 7:15









        lubgrlubgr

        9289




        9289



























            draft saved

            draft discarded
















































            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.




            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            Wikipedia:Vital articles Мазмуну Biography - Өмүр баян Philosophy and psychology - Философия жана психология Religion - Дин Social sciences - Коомдук илимдер Language and literature - Тил жана адабият Science - Илим Technology - Технология Arts and recreation - Искусство жана эс алуу History and geography - Тарых жана география Навигация менюсу

            Bruxelas-Capital Índice Historia | Composición | Situación lingüística | Clima | Cidades irmandadas | Notas | Véxase tamén | Menú de navegacióneO uso das linguas en Bruxelas e a situación do neerlandés"Rexión de Bruxelas Capital"o orixinalSitio da rexiónPáxina de Bruselas no sitio da Oficina de Promoción Turística de Valonia e BruxelasMapa Interactivo da Rexión de Bruxelas-CapitaleeWorldCat332144929079854441105155190212ID28008674080552-90000 0001 0666 3698n94104302ID540940339365017018237

            What should I write in an apology letter, since I have decided not to join a company after accepting an offer letterShould I keep looking after accepting a job offer?What should I do when I've been verbally told I would get an offer letter, but still haven't gotten one after 4 weeks?Do I accept an offer from a company that I am not likely to join?New job hasn't confirmed starting date and I want to give current employer as much notice as possibleHow should I address my manager in my resignation letter?HR delayed background verification, now jobless as resignedNo email communication after accepting a formal written offer. How should I phrase the call?What should I do if after receiving a verbal offer letter I am informed that my written job offer is put on hold due to some internal issues?Should I inform the current employer that I am about to resign within 1-2 weeks since I have signed the offer letter and waiting for visa?What company will do, if I send their offer letter to another company