如何创建并使用unique_ptr 实例(译文)

译自https://docs.microsoft.com/en-us/cpp/cpp/how-to-create-and-use-unique-ptr-instances?view=msvc-160

目录

总述

示例1

示例2

示例3

示例4


总述

unique_ptr does not share its pointer. It cannot be copied to another unique_ptr, passed by value to a function, or used in any C++ Standard Library algorithm that requires copies to be made. A unique_ptr can only be moved. This means that the ownership of the memory resource is transferred to another unique_ptr and the original unique_ptr no longer owns it. We recommend that you restrict an object to one owner, because multiple ownership adds complexity to the program logic. Therefore, when you need a smart pointer for a plain C++ object, use unique_ptr, and when you construct a unique_ptr, use the make_unique helper function.

The following diagram illustrates the transfer of ownership between two unique_ptr instances.

unique_ptr is defined in the <memory> header in the C++ Standard Library. It is exactly as efficient as a raw pointer and can be used in C++ Standard Library containers. The addition of unique_ptr instances to C++ Standard Library containers is efficient because the move constructor of the unique_ptr eliminates the need for a copy operation. 

一个unique_ptr实例不与其他实例共享指针。不能把一个unique_ptr拷贝到另一个unique_ptr实例上,也不能将其值传递给函数,也不能在任何产生其拷贝的c++标准库算法中使用unique_ptr。一个unique_ptr只能被移动。这意味着其指向的(或者说是拥有的)内存资源可以从一个unique_ptr转到另一个unique_ptr名下。我们建议一个对象只有一个拥有者,因为多个拥有者将增加程序逻辑的复杂性。所以,当你需要给一个指向纯c++对象的智能指针时,请使用unique_ptr,并且当你构建一个unique_ptr的实例时,使用make_unique函数。

下面的图展示了(内存资源的)拥有权是如何在两个unique_ptr实例之间传递的。

unique_ptr定义在<memory>头文件中。其效率跟原始的指针一样高,并且可以用在标准库的容器中。在标准库容器中添加unique_ptr的操作是高效的,因为move构造函数并不引起拷贝操作(只是指针的转移)。

示例1

The following example shows how to create unique_ptr instances and pass them between functions.

下面的例子展示了如何创建unique_ptr实例,并且在函数之间传递它们。

unique_ptr<Song> SongFactory(const std::wstring& artist, const std::wstring& title)
{
    // Implicit move operation into the variable that stores the result.
    return make_unique<Song>(artist, title);
}

void MakeSongs()
{
    // Create a new unique_ptr with a new object.
    auto song = make_unique<Song>(L"Mr. Children", L"Namonaki Uta");

    // Use the unique_ptr.
    vector<wstring> titles = { song->title };

    // Move raw pointer from one unique_ptr to another.
    unique_ptr<Song> song2 = std::move(song);

    // Obtain unique_ptr from function that returns by value.
    auto song3 = SongFactory(L"Michael Jackson", L"Beat It");
}

示例2

下面的示例展示如何创建并在vector中使用unique_ptr

void SongVector()
{
    vector<unique_ptr<Song>> songs;
    
    // Create a few new unique_ptr<Song> instances
    // and add them to vector using implicit move semantics.
    songs.push_back(make_unique<Song>(L"B'z", L"Juice")); 
    songs.push_back(make_unique<Song>(L"Namie Amuro", L"Funky Town")); 
    songs.push_back(make_unique<Song>(L"Kome Kome Club", L"Kimi ga Iru Dake de")); 
    songs.push_back(make_unique<Song>(L"Ayumi Hamasaki", L"Poker Face"));

    // Pass by const reference when possible to avoid copying.
    for (const auto& song : songs)
    {
        wcout << L"Artist: " << song->artist << L"   Title: " << song->title << endl; 
    }    
}

In the range for loop, notice that the unique_ptr is passed by reference. If you try to pass by value here, the compiler will throw an error because the unique_ptr copy constructor is deleted.

在for循环中,注意unique_ptr通过引用传递。如果你没有采用引用传递,而是值传递,则编译器将报错,原因是unique_ptr不能拷贝。

示例3

The following example shows how to initialize a unique_ptr that is a class member.

下面的示例介绍的是当unique_ptr是一个成员变量的时候,如何将其初始化。

class MyClass
{
private:
    // MyClass owns the unique_ptr.
    unique_ptr<ClassFactory> factory;
public:

    // Initialize by using make_unique with ClassFactory default constructor.
    MyClass() : factory (make_unique<ClassFactory>())
    {
    }

    void MakeClass()
    {
        factory->DoSomething();
    }
};

示例4

You can use make_unique to create a unique_ptr to an array, but you cannot use make_unique to initialize the array elements.

你可以利用make_unique在数组中创建unique_ptr,但是你不能使用make_unique来对数组元素初始化。

// Create a unique_ptr to an array of 5 integers.
auto p = make_unique<int[]>(5);

// Initialize the array.
for (int i = 0; i < 5; ++i)
{
    p[i] = i;
    wcout << p[i] << endl;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值