[c++] What is a smart pointer and when should I use one?

Let T be a class in this tutorial Pointers in C++ can be divided into 3 types :

1) Raw pointers :

T a;  
T * _ptr = &a; 

They hold a memory address to a location in memory. Use with caution , as programs become complex hard to keep track.

Pointers with const data or address { Read backwards }

T a ; 
const T * ptr1 = &a ; 
T const * ptr1 = &a ;

Pointer to a data type T which is a const. Meaning you cannot change the data type using the pointer. ie *ptr1 = 19 ; will not work. But you can move the pointer. ie ptr1++ , ptr1-- ; etc will work. Read backwards : pointer to type T which is const

  T * const ptr2 ;

A const pointer to a data type T . Meaning you cannot move the pointer but you can change the value pointed to by the pointer. ie *ptr2 = 19 will work but ptr2++ ; ptr2-- etc will not work. Read backwards : const pointer to a type T

const T * const ptr3 ; 

A const pointer to a const data type T . Meaning you cannot either move the pointer nor can you change the data type pointer to be the pointer. ie . ptr3-- ; ptr3++ ; *ptr3 = 19; will not work

3) Smart Pointers : { #include <memory> }

Shared Pointer:

  T a ; 
     //shared_ptr<T> shptr(new T) ; not recommended but works 
     shared_ptr<T> shptr = make_shared<T>(); // faster + exception safe

     std::cout << shptr.use_count() ; // 1 //  gives the number of " 
things " pointing to it. 
     T * temp = shptr.get(); // gives a pointer to object

     // shared_pointer used like a regular pointer to call member functions
      shptr->memFn();
     (*shptr).memFn(); 

    //
     shptr.reset() ; // frees the object pointed to be the ptr 
     shptr = nullptr ; // frees the object 
     shptr = make_shared<T>() ; // frees the original object and points to new object

Implemented using reference counting to keep track of how many " things " point to the object pointed to by the pointer. When this count goes to 0 , the object is automatically deleted , ie objected is deleted when all the share_ptr pointing to the object goes out of scope. This gets rid of the headache of having to delete objects which you have allocated using new.

Weak Pointer : Helps deal with cyclic reference which arises when using Shared Pointer If you have two objects pointed to by two shared pointers and there is an internal shared pointer pointing to each others shared pointer then there will be a cyclic reference and the object will not be deleted when shared pointers go out of scope. To solve this , change the internal member from a shared_ptr to weak_ptr. Note : To access the element pointed to by a weak pointer use lock() , this returns a weak_ptr.

T a ; 
shared_ptr<T> shr = make_shared<T>() ; 
weak_ptr<T> wk = shr ; // initialize a weak_ptr from a shared_ptr 
wk.lock()->memFn() ; // use lock to get a shared_ptr 
//   ^^^ Can lead to exception if the shared ptr has gone out of scope
if(!wk.expired()) wk.lock()->memFn() ;
// Check if shared ptr has gone out of scope before access

See : When is std::weak_ptr useful?

Unique Pointer : Light weight smart pointer with exclusive ownership. Use when pointer points to unique objects without sharing the objects between the pointers.

unique_ptr<T> uptr(new T);
uptr->memFn(); 

//T * ptr = uptr.release(); // uptr becomes null and object is pointed to by ptr
uptr.reset() ; // deletes the object pointed to by uptr 

To change the object pointed to by the unique ptr , use move semantics

unique_ptr<T> uptr1(new T);
unique_ptr<T> uptr2(new T);
uptr2 = std::move(uptr1); 
// object pointed by uptr2 is deleted and 
// object pointed by uptr1 is pointed to by uptr2
// uptr1 becomes null 

References : They can essentially be though of as const pointers, ie a pointer which is const and cannot be moved with better syntax.

See : What are the differences between a pointer variable and a reference variable in C++?

r-value reference : reference to a temporary object   
l-value reference : reference to an object whose address can be obtained
const reference : reference to a data type which is const and cannot be modified 

Reference : https://www.youtube.com/channel/UCEOGtxYTB6vo6MQ-WQ9W_nQ Thanks to Andre for pointing out this question.

Examples related to c++

Method Call Chaining; returning a pointer vs a reference? How can I tell if an algorithm is efficient? Difference between opening a file in binary vs text How can compare-and-swap be used for a wait-free mutual exclusion for any shared data structure? Install Qt on Ubuntu #include errors detected in vscode Cannot open include file: 'stdio.h' - Visual Studio Community 2017 - C++ Error How to fix the error "Windows SDK version 8.1" was not found? Visual Studio 2017 errors on standard headers How do I check if a Key is pressed on C++

Examples related to pointers

Method Call Chaining; returning a pointer vs a reference? lvalue required as left operand of assignment error when using C++ Error: stray '\240' in program Reference to non-static member function must be called How to convert const char* to char* in C? Why should I use a pointer rather than the object itself? Function stoi not declared C pointers and arrays: [Warning] assignment makes pointer from integer without a cast Constant pointer vs Pointer to constant How to get the real and total length of char * (char array)?

Examples related to c++11

Remove from the beginning of std::vector Converting std::__cxx11::string to std::string What exactly is std::atomic? C++ How do I convert a std::chrono::time_point to long and back Passing capturing lambda as function pointer undefined reference to 'std::cout' Is it possible to use std::string in a constexpr? How does #include <bits/stdc++.h> work in C++? error::make_unique is not a member of ‘std’ no match for ‘operator<<’ in ‘std::operator

Examples related to smart-pointers

Is there any use for unique_ptr with array? Example to use shared_ptr? Why can I not push_back a unique_ptr into a vector? Where is shared_ptr? What is a smart pointer and when should I use one?

Examples related to c++-faq

What are the new features in C++17? Why should I use a pointer rather than the object itself? Why is enum class preferred over plain enum? gcc/g++: "No such file or directory" What is an undefined reference/unresolved external symbol error and how do I fix it? When is std::weak_ptr useful? What XML parser should I use in C++? What is a lambda expression in C++11? Why should C++ programmers minimize use of 'new'? Iterator invalidation rules