© Mikael Olsson 2018
Mikael OlssonC++17 Quick Syntax Referencehttps://doi.org/10.1007/978-1-4842-3600-0_27

27. Smart Pointers

Mikael Olsson1 
(1)
Hammarland, Finland
 

Several smart pointer classes were added in C++11 for managing dynamically allocated memory. By using these container classes, instead of raw pointers, it is no longer necessary to manually delete objects created with the new keyword. This simplifies coding by helping to prevent memory leaks.

Unique Pointer

The first smart pointer that we look at is the unique pointer (std::unique_ptr), which simply acts as a container for a raw pointer. It replaces another deprecated smart pointer named auto_ptr, which was removed in C++17. Consider the following example on how to use a unique pointer.

#include <memory> // include smart pointers
#include <iostream>
using namespace std;
struct Foo
{
  int val;
  Foo() { cout << "1"; }
 ~Foo() { cout << "3"; }
};
int main()
{
  unique_ptr<Foo> p(new Foo()); // "1"
  p->val = 2;
  cout << p->val; // "2"
} // "3"

The output of this code is "123" as the pointer is created, used, and then destroyed automatically when it goes out of scope. Note that the smart pointer is created not through assignment but instead by passing a raw pointer to its constructor. Once created, however, the smart pointer is used just as a regular pointer, in this case with the arrow operator (->) to dereference the pointer and access the member of the object in a single operation.

As the name implies, a unique pointer has exclusive ownership of the object it points to and therefore cannot be copied. It can, however, transfer ownership to another unique pointer using the std::move function. After completing such a transfer, the original pointer will be set to nullptr.

unique_ptr<Foo> u1(new Foo());
unique_ptr<Foo> u2 = u1; // compile-time error
unique_ptr<Foo> u3 = move(u1); // transfers ownership

Shared Pointer

In cases where shared ownership of a dynamically allocated object is necessary, there is the shared pointer (std::shared_ptr). Unlike the unique pointer, a shared pointer can be copied. The memory to the object will not be deallocated until the last remaining shared pointer owning the object is destroyed, either by going out of scope or by resetting the pointer to nullptr manually.

shared_ptr<Foo> s1(new Foo());
shared_ptr<Foo> s2 = s1; // extends ownership
s1 = nullptr; // reset pointer
s2 = nullptr; // reset last pointer and delete memory

As of C++14, use of the new keyword is discouraged in most circumstances. Instead, the std::make_unique and std::make_shared functions are recommended when allocating dynamic memory .

unique_ptr<Foo> u = make_unique<Foo>();
shared_ptr<Foo> s = make_shared<Foo>();

Weak Shared Pointer

A weak shared pointer (std::weak_ptr) can be created from a shared pointer. Unlike the shared pointer, a weak shared pointer is non-owning, meaning that the object will be cleaned up when all shared pointers go out of scope, regardless of any weak shared pointers. In order to access the referenced object, a weak shared pointer must first be converted into a shared pointer using the lock method. Here is an example to illustrate.

#include <memory>
#include <iostream>
using namespace std;
void observe(weak_ptr<int> weak)
{
  shared_ptr<int> s = weak.lock();
  if (s != nullptr) {
    cout << "Pointer is " << *s << endl;
  }
  else {
    cout << "Pointer has expired" << endl;
  }
}
int main()
{
  shared_ptr<int> s = make_shared<int>(5);
  weak_ptr<int> w = s; // copy pointer without ownership
  observe(w); // "Pointer is 5"
  s = nullptr; // delete managed object
  observe(w); // "Pointer has expired"
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.224.62.105