Overview
unique_ptr are useful when a resource such as a piece of memory or a file handle needs to be singly managed.
Details
unique_ptr
unique_ptr are useful when a single resource such as a piece of memory or a file handle is allocated, used in multiple places and later recycled.
unique_ptr is replacement for auto_ptr. It can hold a single resource such as a pointer to an object or an array of objects. It also provides option to supply a custom deleter object to recycle the resource when the unique_ptr is destroyed. If not supplied, default_delete is used.It has complete ownership of the resource it's holding. When the unique_ptr object is destroyed gracefully or during stack rewind. , the deleter will be called to free up resources.
Syntax
template <class T, class D = default_delete<T>> class unique_ptr //array specialization template <class T, class D> class unique_ptr<T[],D>
member types
Name | Description |
---|---|
element_type | first template parameter (T). The type of the managed object |
deleter_type | second template parameter (D). The type of the stored deleter. Defaults to default_delete<T> |
pointer | remove_reference<D>::type::pointer, if this type exists T*, otherwise The pointer type. |
Constructors
Commonly used constructors defined for unique_ptr<T>.
Name | Description |
---|---|
unique_ptr() | Default constructor. Example:
|
unique_ptr(nullptr_t) | Same as default constructor. Example: unique_ptr<int>(nullptr); |
unique_ptr(pointer p) | Takes ownership of p and use default deleter Example: unique_ptr<int>(new int(10)); |
unique_ptr (pointer p, typename conditional<is_reference<D>::value,D,const D&> del) | Takes ownership of p and copy lvalue deleter del Example: auto d = default_delete<int>(); unique_ptr<int> (new int, d); |
unique_ptr (pointer p, typename remove_reference<D>::type&& del) | Takes ownership of p and move rvalue deleter del Example: unique_ptr<int> (new int, default_delete<int>()); |
unique_ptr(unique_ptr&& x) | Move pointer and copy deleter from x if it's a reference or else move it. Example: unique_ptr<int> x(new int, default_delete<int>()); unique_ptr<int> (move(x)); |
template <typename U, typename E> unique_ptr (unique_ptr<U,E>&& x) | move pointer and copy deleter from x if it's a reference or else move it. Example: unique_ptr<int> t(new int, default_delete<int>()); unique_ptr<int> x (move(t)); unique_ptr<int>(move(x)); |
unique_ptr<T>(auto_ptr<T>&& x) | takes ownership of autoptr x Example: auto_ptr<int> x(new int); unique_ptr<int> (move(x)); |
Methods
The following describes functionality in detail.
Name | Description |
---|---|
pointer get() | Returns the pointer of the resource it's holding without relinquishing the ownership. Example unique_ptr<int[]> x(new int[10], default_delete<int[]>()); x.get()[3]=10; |
pointer release() | Returns the pointer of the resource it's holding also relinquishes the ownership without calling the deleter. Example unique_ptr<int[]> x(new int[10], default_delete<int[]>()); auto p = x.release(); p[5]=10; delete [] p; |
| Destroys the resource it's currently holding by calling deleter and releases the resource. Optionally new resource can be set to it.
cout << boolalpha; unique_ptr<long[]> x(new long[10], default_delete<long[]>()); x.reset(); //prints false cout << (bool)x << endl; x.reset(new long[10]); //prints true cout << (bool)x << endl; |
operator bool() | Returns true if a resource is managed otherwise false. |
typename add_lvalue_reference<T>::type operator*() | Object dereferencing. Returns the object owned, equivalent to *get(). |
pointer operator->() | Member dereferencing. Returns a pointer to the object owned, equivalent to get(). Example struct person {string name; unsigned char age;}; unique_ptr<person> x(new person("khrisha",6)); //prints khrisha cout << x->name << endl; //prints 6 cout << (short) (*x).age << endl; |
element_type& operator[](size_t i) | Array accessing index operator. Returns a reference to the i-th object (zero-based) in the managed array, equivalent to: get()[i]. This member function is exclusive of the array-specialization of unique_ptr (unique_ptr<T[],D>). The non-specialized version does not include it. Example unique_ptr<long[]> x(new long[10], default_delete<long[]>()); x[5]=5; |
|
|
|
|
The example 3 demonstrates it.
External Methods
The following describes relational operators
Name | Description |
---|---|
| Equality operator. |
| Inequality operator. |
| Greater than operator. |
| Greater than or equal to operator. |
| Less than operator. |
| Less than or equal to operator. |
make_unique()
A template based function to generate unique_ptr.
Syntax
//scalar types template< class T, class... Args > unique_ptr<T> make_unique( Args&&... args ); //array types template< class T > unique_ptr<T> make_unique( std::size_t size );
Example
auto p = make_unique<int>(10); //prints 10 cout << *p << endl; auto p2 = make_unique<pair<int,int>>(10,20); //prints 10 20 cout << p2->first << " " << p2->second << endl; auto p3 = make_unique<int[]>(4); p3[0]=10; //prints 10 cout << p3[0] << endl;
Usage Examples
Doubly linked list
A double linked list can be implemented using unique_ptr. The advantage is automatic cleanup. However, each node should be owned by a single unique_ptr. Double referencing same node can be avoided by declaring each node as below. Here head of the list and next pointer of each node are owners . Rest are all pointers to the same.
struct doublelist { struct node; using LLNODE = unique_ptr<node>; using LLNODEptr = unique_ptr<node>*; struct node { T data; LLNODEptr prev; LLNODE next; }; LLNODE head; LLNODEptr tail; }
The example 4 depicts a solution.
No comments:
Post a Comment