Smart Pointers

Smart Pointers

TDDD38 APiC++ Smartpointers 317 Smart pointers A smart pointer stores a pointer to another object. • simplifies resource management – can prevent memory leaks if exceptions are thrown – can help ensure that resources are available as long as they are needed, and disposed of when no longer needed • strong and weak references –astrong reference protects the referenced object from garbage collection – an object referenced only by weak references is considered unreachable and may be collected at any time • C++ provide strong/weak reference functionality for pointers – include <memory> – raw pointers are basically weak, but not true weak, since they don’t know when the referenced object becomes unreachable • shared_ptr (strong) – reference counting smart pointer – the controlled resource is released when the use count (reference count) becomes 0 (unreachable) – supports copy semantics – shared_ptrs may be stored in containers • weak_ptr (weak) – are like raw pointers, but know when they dangle (have expired) • unique_ptr (strong) – supports moving instead of copying File: Standard-Smart-Pointers-OH-en © 2014 Tommy Olsson, IDA, Linköpings universitet (2014-11-13) TDDD38 APiC++ Smartpointers 318 unique_ptr (1) • retains sole ownership of an object through a pointer and destroys that object when the unique_ptr goes out of scope template <class T, class D = default_delete<T>> class unique_ptr { … }; {//some block unique_ptr<Object> up1{ new Object }; // single object version unique_ptr<Object[]> up2{ new Object[10] }; // array version unique_ptr<Object> up3{ up1 }; // error – copy constructor is removed up1 = up3; // error – copy assignment is removed unique_ptr<Object> up4{ std::move(up1) }; // ownership is transferred to up4 up1 = std::move(up4); // ownership is transferred to up1 } • will dispose of the pointed-to object when destroyed itself – for example when leaving block scope – this is done with an associated deleter • typical uses – providing exception safety by deleting dynamically allocated objects on both normal exit and exit through exception – transferring ownership of uniquely-owned objects with dynamic lifetime into functions (argument passing) – acquiring ownership of uniquely-owned objects with dynamic lifetime from functions (return value) – as the element type in move-aware containers, such as std::vector, which hold pointers to dynamically-allocated objects File: Standard-Smart-Pointers-OH-en © 2014 Tommy Olsson, IDA, Linköpings universitet (2014-11-13) TDDD38 APiC++ Smartpointers 319 unique_ptr (2) • constructors unique_ptr<T> up1; // default constructor – up1 owns nothing unique_ptr<T> up2{ nullptr }; // up2 owns nothing unique_ptr<T> up3{ new T }; // taking a pointer to an object – up3 owns the pointed to object unique_ptr<T> up4{ std::move(up3) }; // move constructor – ownership is transferred to up4 unique_ptr<U> up5{ std::move(up4) }; // type converting constructor – ownership is transferred – there is also a constructor for passing an auto_ptr smart pointer (C++98, deprecated in C++11) – there are also versions taking a deleter • destructor – deletes the owned object • assignment up1 = std::move(up2); // move assignment – up2 becomes nullpointer up1 = nullptr;//becomes as if default initialized up1 = std::move(up5); // type converting assignment, also the deleter will be converted File: Standard-Smart-Pointers-OH-en © 2014 Tommy Olsson, IDA, Linköpings universitet (2014-11-13) TDDD38 APiC++ Smartpointers 320 unique_ptr (3) • observers cout << *up << endl; // up must not be nullptr cout << up->memfun() << endl; // up must not be nullptr cout << up.get()->memfun() << endl; // get() returns the stored pointer cout << up2[i] << endl; // array version elements are indexable if (up) cout << up->memfun() << endl; // true if stored pointer is not nullptr unique_ptr<Object>::deleter_type = get_deleter(); • modifiers Object* p{ up.release() }; // sets up to nullptr up.reset(p); // assigns new pointer, and then calls the deleter for the old pointer, if not nullptr up1.swap(up2); // swaps pointers and deleters – also non-member version up.reset(new int(2)) // assigns new pointer, and then calls the deleter for the old pointer • comparisons – memory locations compared == != < <= > >= File: Standard-Smart-Pointers-OH-en © 2014 Tommy Olsson, IDA, Linköpings universitet (2014-11-13) TDDD38 APiC++ Smartpointers 321 Standard library default deleters • the single object deleter calls delete on the stored pointer – defined as primary template template <typename T> struct default_delete { constexpr default_delete() noexcept = default; template <typename U> default_delete(const default_delete<U>&) noexcept; void operator()(T* ptr) const { static_assert(sizeof(T) > 0, "can’t delete pointer to incomplete type"); delete ptr; } }; • the array deleter is declared as an explicit specialization, which calls delete[] on the stored pointer template <typename T> struct default_delete<T[]> { constexpr default_delete() noexcept = default; void operator()(T* ptr) const { static_assert(sizeof(T) > 0, "can’t delete pointer to incomplete type"); delete[] ptr; } template <typename U> void operator()(U*) const = delete; }; File: Standard-Smart-Pointers-OH-en © 2014 Tommy Olsson, IDA, Linköpings universitet (2014-11-13) TDDD38 APiC++ Smartpointers 322 Shared-ownership pointers • Implements semantics of shared ownership – stores a pointer, usually obtained via new – the last remaining owner of the pointer is responsible for destroying the object, or – otherwise releasing the resources associated with the stored pointer • Two associated smart pointer types – shared_ptr – weak_ptr File: Standard-Smart-Pointers-OH-en © 2014 Tommy Olsson, IDA, Linköpings universitet (2014-11-13) TDDD38 APiC++ Smartpointers 323 shared_ptr • a shared_ptr object can take ownership of a pointer and manage the storage of that pointer shared_ptr<int> sp1{ new int{ 17 } }; // use count is set to 1 – provide a limited garbage-collection facility • shared_ptr objects can share ownership shared_ptr<int> sp2{ sp1 }; // use count is increased to 2 – the group of owners becomes responsible to delete the pointer when the last of them releases ownership • shared_ptr objects can only share ownership by copying their values – two shared_ptr objects constructed from the same (non-shared) pointer will both own the pointer without sharing it int* p = new int{ 4711 }; shared_ptr<int> sp3{ p }; // use count is set to 1 shared_ptr<int> sp4{ p }; // use count is set to 1 – if one such shared_ptr releases the pointer, deleting the managed object, leaves the other pointing to an invalid location • ownership is released as soon as a shared pointer object is – destroyed – changed by an assignment – changed by a call to reset() if the use count is 1 when this happens, the managed pointer is deleted File: Standard-Smart-Pointers-OH-en © 2014 Tommy Olsson, IDA, Linköpings universitet (2014-11-13) TDDD38 APiC++ Smartpointers 324 Inside shared_ptr shared_ptr object control block (on heap) use count: 1 (strong count) weak count: 0 (on heap) • if several shared_ptr shares ownership of object they will also share the control block – use count (strong count) stores the number of strong references, i.e. shared_ptr, referring to object – weak count stores the number of weak references, i.e. weak_ptr, referring to object (none above) File: Standard-Smart-Pointers-OH-en © 2014 Tommy Olsson, IDA, Linköpings universitet (2014-11-13) TDDD38 APiC++ Smartpointers 325 shared_ptr operations (1) • constructors shared_ptr<int> sp1; // default constructor – sp1 is empty, use count of zero shared_ptr<int> sp2{ nullptr }; // from null pointer – same as default construction shared_ptr<int> sp3{ new int{17} }; // from pointer – sp3 owns the pointer, use count is set to 1 shared_ptr<int> sp4{ sp3 }; // copy constructor – if sp3 is not empty ownership is shared shared_ptr<int> sp5{ std::move(sp3) }; // move constructor – sp3 becomes empty, as if default-constructed shared_ptr<int> sp6{ wp }; // copy from weak_ptr – bad_weak_ptr thrown if wp has expired shared_ptr<int> sp7{ up }; // move from unique_ptr, or auto_ptr – aliasing constructor – example later • destructor – if use count is greater than 1, the use count of the other objects sharing ownership is decreased by 1 – if use count is 1 (last referrer) the owned object is deleted – if use count is 0 (empty shared_ptr) the destructor has no side effects File: Standard-Smart-Pointers-OH-en © 2014 Tommy Olsson, IDA, Linköpings universitet (2014-11-13) TDDD38 APiC++ Smartpointers 326 shared_ptr operations (2) • assignment sp1 = sp2; // copy assignment – add sp1 as a shared owner to sp2’s assets sp1 = std::move(sp2); // move assignment – transfer ownership from sp2 to sp1, sp2 becomes empty sp1 = std::move(up); // move from unique_ptr (or auto_ptr) – ownership is transferred, use count set to 1 sp1 = nullptr;//managed pointer is deleted, since use count is 1 – sp1 becomes empty – a call to an assignment operator has the same effect as if the shared_ptr destructor was called before the value is changed, including the deletion of the managed object if use count was 1 (pointer was unique) – the value of a pointer cannot be assigned directly to a shared_ptr object sp1 = std::make_shared<int>(17); // make_shared returns shared_ptr<int> (copy assignment) sp1.reset(new int{ 17 }); – a call to reset() has the same effect as if the shared_ptr destructor was called before the value is changed File: Standard-Smart-Pointers-OH-en © 2014 Tommy Olsson, IDA, Linköpings universitet (2014-11-13)

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    20 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us