您的位置:首页 > 编程语言 > C语言/C++

c++11 & 14: unique_ptr shared_ptr std::make_unique(c++14)

2015-07-02 11:21 519 查看
参考网站:
http://www.cplusplus.com/reference/utility/pair/
Both of these classes are smart pointers, which means that they automatically (in most cases) will deallocate the object that they point at when that object can no longer be referenced. The difference between the two is how many different pointers of each type
can refer to a resource.

When using
unique_ptr
,
there can be at most one
unique_ptr
pointing
at any one resource. When that
unique_ptr
is
destroyed, the resource is automatically reclaimed. Because there can only be one
unique_ptr
to
any resource, any attempt to make a copy of a
unique_ptr
will
cause a compile-time error. For example, this code is illegal:
unique_ptr<T> myPtr(new T);       // Okay
unique_ptr<T> myOtherPtr = myPtr; // Error: Can't copy unique_ptr


However,
unique_ptr
can
be moved using the new move semantics:
unique_ptr<T> myPtr(new T);                  // Okay
unique_ptr<T> myOtherPtr = std::move(myPtr); // Okay, resource now stored in myOtherPtr


Similarly, you can do something like this:
unique_ptr<T> MyFunction() {
unique_ptr<T> myPtr(/* ... */);

/* ... */

return myPtr;
}


This idiom means "I'm returning a managed resource to you. If you don't explicitly capture the return value, then the resource will be cleaned up. If you do, then you now have exclusive ownership of that resource." In this way, you can think of
unique_ptr
as
a safer, better replacement for
auto_ptr
.

shared_ptr
,
on the other hand, allows for multiple pointers to point at a given resource. When the very last
shared_ptr
to
a resource is destroyed, the resource will be deallocated. For example, this code is perfectly legal:
shared_ptr<T> myPtr(new T);       // Okay
shared_ptr<T> myOtherPtr = myPtr; // Sure!  Now have two pointers to the resource.


Internally,
shared_ptr
uses reference
counting to track how many pointers refer to a resource, so you need to be careful not to introduce any reference cycles.

In short:

Use
unique_ptr
when
you want a single pointer to an object that will be reclaimed when that single pointer is destroyed.
Use
shared_ptr
when
you want multiple pointers to the same resource.

Hope this helps!


std::make_unique

C++

Utilities library

Dynamic memory management

std::unique_ptr

Defined in header
<memory>

template< class T, class... Args >

unique_ptr<T> make_unique( Args&&... args );
(1)(since C++14)

(only for non-array types)
template< class T >

unique_ptr<T> make_unique( std::size_t size );
(2)(since C++14)

(only for array types with unknown bound)
template< class T, class... Args >

/* unspecified */ make_unique( Args&&... args ) = delete;
(3)(since C++14)

(only for array types with known bound)
Constructs an object of type
T
and wraps it in a std::unique_ptr.
1) Constructs a non-array type
T
.
The arguments
args
are passed to the constructor of
T
.
The function does not participate in the overload resolution if
T
is an array type. The function is equivalent to:

unique_ptr<T>(new T(std::forward<Args>(args)...))


2) Constructs an array of unknown bound
T
.
The function does not participate in the overload resolution unless
T
is an array of unknown bound. The function is
equivalent to:

unique_ptr<T>(new typename std::remove_extent<T>::type[size]())


3) Construction of arrays of known bound is disallowed.


Parameters

args-list of arguments with which an instance of
T
will be
constructed.
size-the size of the array to construct


Return value

std::unique_ptr of
an instance of type
T
.


Exceptions

May throw std::bad_alloc or any exception thrown by the constructor of
T
.
If an exception is thrown, this function has no effect.


Example

Run this code

#include <iostream>
#include <memory>

struct Vec3
{
int x, y, z;
Vec3() : x(0), y(0), z(0) { }
Vec3(int x, int y, int z) :x(x), y(y), z(z) { }
friend std::ostream& operator<<(std::ostream& os, Vec3& v) {
return os << '{' << "x:" << v.x << " y:" << v.y << " z:" << v.z  << '}';
}
};

int main()
{
// Use the default constructor.
std::unique_ptr<Vec3> v1 = std::make_unique<Vec3>();
// Use the constructor that matches these arguments
std::unique_ptr<Vec3> v2 = std::make_unique<Vec3>(0, 1, 2);
// Create a unique_ptr to an array of 5 elements
std::unique_ptr<Vec3[]> v3 = std::make_unique<Vec3[]>(5);

std::cout << "make_unique<Vec3>():      " << *v1 << '\n'
<< "make_unique<Vec3>(0,1,2): " << *v2 << '\n'
<< "make_unique<Vec3[]>(5):   " << '\n';
for (int i = 0; i < 5; i++) {
std::cout << "     " << v3[i] << '\n';
}
}


Output:

make_unique<Vec3>():      {x:0 y:0 z:0}
make_unique<Vec3>(0,1,2): {x:0 y:1 z:2}
make_unique<Vec3[]>(5):
{x:0 y:0 z:0}
{x:0 y:0 z:0}
{x:0 y:0 z:0}
{x:0 y:0 z:0}
{x:0 y:0 z:0}



See also

(constructor)

constructs a new
unique_ptr


(public member function)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: