std::unique_ptr is a smart pointer introduced in C++11. It automatically manages the dynamically allocated resources on the heap. Smart pointers are just wrappers around regular old pointers that help you prevent widespread bugs. Namely, forgetting to delete a pointer and causing a memory leak or accidentally deleting a pointer twice or in the wrong way. They can be used in a similar way to standard pointers. They automate some of the manual processes that cause common bugs.
Prerequisites: Pointer in C++, Smart Pointers in C++.
Syntax
unique_ptr<A> ptr1 (new A)
Here,
- unique_ptr<A>: It specifies the type of the std::unique_ptr. In this case- an object of type A.
- new A: An object of type A is dynamically allocated on the heap using the new operator.
- ptr1: This is the name of the std::unique_ptr variable.
What happens when unique_ptr is used?
When we write unique_ptr<A> ptr1 (new A), memory is allocated on the heap for an instance of datatype A. ptr1 is initialized and points to newly created A object. Here, ptr1 is the only owner of the newly created object A and it manages this object's lifetime. This means that when ptr1 is reset or goes out of scope, memory is automatically deallocated and A's object is destroyed.
When to use unique_ptr?
When ownership of resource is required. When we want single or exclusive ownership of a resource, then we should go for unique pointers. Only one unique pointer can point to one resource. So, one unique pointer cannot be copied to another. Also, it facilitates automatic cleanup when dynamically allocated objects go out of scope and helps preventing memory leaks.
Note: We need to use the <memory> header file for using these smart pointers.
Examples of Unique_ptr
Example 1:
Lets create a structure A and it will have a method named printA to display some text. Then in the main section, let's create a unique pointer that will point to the structure A. So at this point, we have an instance of structure A and p1 holds the pointer to that.
C++
// C++ Program to implement unique_ptr
#include <iostream>
#include <memory>
using namespace std;
struct A {
void printA() { cout << "A struct...." << endl; }
};
int main()
{
unique_ptr<A> p1(new A);
p1->printA();
// displays address of the containing pointer
cout << p1.get() << endl;
return 0;
}
OutputA struct....
0x18dac20
Example 2
Now let's create another pointer p2 and we will try to copy the pointer p1 using the assignment operator(=).
C++
// C++ Program to implement unique_ptr
#include <iostream>
#include <memory>
using namespace std;
struct A {
void printA() { cout << "A struct...." << endl; }
};
int main()
{
unique_ptr<A> p1(new A);
p1->printA();
// displays address of the containing pointer
cout << p1.get() << endl;
// will give compile time error
unique_ptr<A> p2 = p1;
p2->printA();
return 0;
}
Output
main.cpp: In function ‘int main()’:
main.cpp:18:24: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = A; _Dp = std::default_delete]’
18 | unique_ptr<A> p2 = p1;
| ^~
In file included from /usr/include/c++/11/memory:76,
from main.cpp:3:
/usr/include/c++/11/bits/unique_ptr.h:468:7: note: declared here
468 | unique_ptr(const unique_ptr&) = delete;
| ^~~~~~~~~~
The above code will give compile time error as we cannot assign pointer p2 to p1 in case of unique pointers. We have to use the move semantics for such purpose as shown below.
Example 3
Managing object of type A using move semantics.
C++
// C++ Program to implement unique_ptr
#include <iostream>
#include <memory>
using namespace std;
struct A {
void printA() { cout << "A struct...." << endl; }
};
int main()
{
unique_ptr<A> p1(new A);
p1->printA();
// displays address of the containing pointer
cout << p1.get() << endl;
// now address stored in p1 shpould get copied to p2
unique_ptr<A> p2 = move(p1);
p2->printA();
cout << p1.get() << endl;
cout << p2.get() << endl;
return 0;
}
OutputA struct....
0x2018c20
A struct....
0
0x2018c20
Note once the address in pointer p1 is copied to pointer p2, the pointer p1's address becomes NULL(0) and the address stored by p2 is now the same as the address stored by p1 showing that the address in p1 has been transferred to the pointer p2 using the move semantics.
Similar Reads
std::unique in C++
In C++, std::unique is used to remove duplicates of any element present consecutively in a range[first, last). It performs this task for all the sub-groups present in the range having the same element present consecutively. It does not delete all the duplicate elements, but it removes duplicacy by j
7 min read
std::unique_copy in C++
std::unique is used to remove duplicates of any element present consecutively in a range[first, last). It performs this task for all the sub-groups present in the range having the same element present consecutively. But, what if we don't want to alter with the original range and just want the result
6 min read
list unique() in C++ STL
list::unique() is an inbuilt function in C++ STL which removes all duplicate consecutive elements from the list. It works only on sorted list. Syntax: list_name.unique(BinaryPredicate name) Parameters: The function accepts a single and optional parameter which is a binary predicate that returns true
2 min read
weak_ptr in C++
The weak_ptr is one of the smart pointers that provide the capability of a pointer with some reduced risks as compared to the raw pointer. The weak_ptr, just like shared_ptr has the capability to point to the resource owned by another shared_ptr but without owning it. In other words, they are able t
3 min read
std::make_unique in C++ 14
std::make_unique is a utility function in C++ that was introduced in C++14. It is used to create a unique_ptr object, which is a smart pointer that manages the lifetime of dynamically allocated objects. It is defined inside <memory> header file. Syntaxstd::make_unique <object_type> (argu
2 min read
shared_ptr in C++
std::shared_ptr is one of the smart pointers introduced in C++11. Unlike a simple pointer, it has an associated control block that keeps track of the reference count for the managed object. This reference count is shared among all the copies of the shared_ptr instances pointing to the same object, e
5 min read
'this' pointer in C++
In C++, 'this' pointers is a pointer to the current instance of a class. It is used to refer to the object within its own member functions. In this article, we will learn how to use 'this' pointer in C++. Let's take a look at an example: [GFGTABS] C++ #include <iostream> using namespace std; /
5 min read
void Pointer in C++
In C++, a void pointer is a pointer that is declared using the 'void' keyword (void*). It is different from regular pointers it is used to point to data of no specified data type. It can point to any type of data so it is also called a "Generic Pointer". Syntax of Void Pointer in C++void* ptr_name;
7 min read
forward_list::unique() in C++ STL
forward_list::unique() is an inbuilt function in C++ STL which removes all consecutive duplicate elements from the forward_list. It uses binary predicate for comparison. Syntax: forwardlist_name.unique(BinaryPredicate name)Parameters: The function accepts a single parameter which is a binary predica
2 min read
Understanding nullptr in C++
Consider the following C++ program that shows problem with NULL (need of nullptr) [GFGTABS] CPP // C++ program to demonstrate problem with NULL #include <bits/stdc++.h> using namespace std; // function with integer argument void fun(int N) { cout << "fun(int)"; return;} // Over
3 min read