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

            Club Baloncesto Breogán Índice Historia | Pavillón | Nome | O Breogán na cultura popular | Xogadores | Adestradores | Presidentes | Palmarés | Historial | Líderes | Notas | Véxase tamén | Menú de navegacióncbbreogan.galCadroGuía oficial da ACB 2009-10, páxina 201Guía oficial ACB 1992, páxina 183. Editorial DB.É de 6.500 espectadores sentados axeitándose á última normativa"Estudiantes Junior, entre as mellores canteiras"o orixinalHemeroteca El Mundo Deportivo, 16 setembro de 1970, páxina 12Historia do BreogánAlfredo Pérez, o último canoneiroHistoria C.B. BreogánHemeroteca de El Mundo DeportivoJimmy Wright, norteamericano do Breogán deixará Lugo por ameazas de morteResultados de Breogán en 1986-87Resultados de Breogán en 1990-91Ficha de Velimir Perasović en acb.comResultados de Breogán en 1994-95Breogán arrasa al Barça. "El Mundo Deportivo", 27 de setembro de 1999, páxina 58CB Breogán - FC BarcelonaA FEB invita a participar nunha nova Liga EuropeaCharlie Bell na prensa estatalMáximos anotadores 2005Tempada 2005-06 : Tódolos Xogadores da Xornada""Non quero pensar nunha man negra, mais pregúntome que está a pasar""o orixinalRaúl López, orgulloso dos xogadores, presume da boa saúde económica do BreogánJulio González confirma que cesa como presidente del BreogánHomenaxe a Lisardo GómezA tempada do rexurdimento celesteEntrevista a Lisardo GómezEl COB dinamita el Pazo para forzar el quinto (69-73)Cafés Candelas, patrocinador del CB Breogán"Suso Lázare, novo presidente do Breogán"o orixinalCafés Candelas Breogán firma el mayor triunfo de la historiaEl Breogán realizará 17 homenajes por su cincuenta aniversario"O Breogán honra ao seu fundador e primeiro presidente"o orixinalMiguel Giao recibiu a homenaxe do PazoHomenaxe aos primeiros gladiadores celestesO home que nos amosa como ver o Breo co corazónTita Franco será homenaxeada polos #50anosdeBreoJulio Vila recibirá unha homenaxe in memoriam polos #50anosdeBreo"O Breogán homenaxeará aos seus aboados máis veteráns"Pechada ovación a «Capi» Sanmartín e Ricardo «Corazón de González»Homenaxe por décadas de informaciónPaco García volve ao Pazo con motivo do 50 aniversario"Resultados y clasificaciones""O Cafés Candelas Breogán, campión da Copa Princesa""O Cafés Candelas Breogán, equipo ACB"C.B. Breogán"Proxecto social"o orixinal"Centros asociados"o orixinalFicha en imdb.comMario Camus trata la recuperación del amor en 'La vieja música', su última película"Páxina web oficial""Club Baloncesto Breogán""C. B. Breogán S.A.D."eehttp://www.fegaba.com

            Vilaño, A Laracha Índice Patrimonio | Lugares e parroquias | Véxase tamén | Menú de navegación43°14′52″N 8°36′03″O / 43.24775, -8.60070

            Cegueira Índice Epidemioloxía | Deficiencia visual | Tipos de cegueira | Principais causas de cegueira | Tratamento | Técnicas de adaptación e axudas | Vida dos cegos | Primeiros auxilios | Crenzas respecto das persoas cegas | Crenzas das persoas cegas | O neno deficiente visual | Aspectos psicolóxicos da cegueira | Notas | Véxase tamén | Menú de navegación54.054.154.436928256blindnessDicionario da Real Academia GalegaPortal das Palabras"International Standards: Visual Standards — Aspects and Ranges of Vision Loss with Emphasis on Population Surveys.""Visual impairment and blindness""Presentan un plan para previr a cegueira"o orixinalACCDV Associació Catalana de Cecs i Disminuïts Visuals - PMFTrachoma"Effect of gene therapy on visual function in Leber's congenital amaurosis"1844137110.1056/NEJMoa0802268Cans guía - os mellores amigos dos cegosArquivadoEscola de cans guía para cegos en Mortágua, PortugalArquivado"Tecnología para ciegos y deficientes visuales. Recopilación de recursos gratuitos en la Red""Colorino""‘COL.diesis’, escuchar los sonidos del color""COL.diesis: Transforming Colour into Melody and Implementing the Result in a Colour Sensor Device"o orixinal"Sistema de desarrollo de sinestesia color-sonido para invidentes utilizando un protocolo de audio""Enseñanza táctil - geometría y color. Juegos didácticos para niños ciegos y videntes""Sistema Constanz"L'ocupació laboral dels cecs a l'Estat espanyol està pràcticament equiparada a la de les persones amb visió, entrevista amb Pedro ZuritaONCE (Organización Nacional de Cegos de España)Prevención da cegueiraDescrición de deficiencias visuais (Disc@pnet)Braillín, un boneco atractivo para calquera neno, con ou sen discapacidade, que permite familiarizarse co sistema de escritura e lectura brailleAxudas Técnicas36838ID00897494007150-90057129528256DOID:1432HP:0000618D001766C10.597.751.941.162C97109C0155020