c++11学习笔记(6)- 智能指针

原创

智能指针在C++11以前就已经存在了,使用的是 auto_ptr 作为只能指针,不过 auto_ptr 有一个缺点,拷贝时返回一个左值,不能调用delete[]等,所以在C++11中被弃用了。C++11中使用 unique_ptrshared_ptrweak_ptr 等智能指针回收堆分配的对象。

1. unique_ptr

  • 与所指对象的内存紧密绑定,不与其他 unique_ptr 类型的指针对象共享所指对象的内存。
  • 从实现上讲, unique_ptr 则是一个删除了拷贝构造函数、保留了移动构造函数的指针封装类型。程序员仅可以使用右值对 unique_ptr 对象进行构造,而且一旦构造成功,右值对象中的指针就会被“窃取”,因此该右值对象即刻失去对指针的所有权。

我们来看下面的一个例子:

#include <iostream>
#include <memory>
#include <stdlib.h>

int main(int argc, char** argv)
{
    std::unique_ptr<int> pUniquePtr(new int(10));

    std::cout << *pUniquePtr << std::endl;

    std::unique_ptr<int> pUniquePtr2 = std::move(pUniquePtr);
    std::cout << *pUniquePtr2 << std::endl;

    // std::cout << *pUniquePtr << std::endl; (此句运行崩溃)

    system("pause");
    return 0;
}

程序的运行结果为
10
10

如果在程序的第14行的注释去掉,则运行崩溃,因为指针对象已经被 pUniquePtr2 窃取了。


2. shared_ptr

unique_ptr 不同, shared_ptr 实际上采用的引用计数,所以一旦一个 shared_ptr 指针放弃了所有权,其他的 shared_ptr 对象不会受到影响,当引用计数为0的时候才释放指向的堆内存。

下面是一个简单的示例:

#include <iostream>
#include <memory>
#include <stdlib.h>

int main(int argc, char** argv)
{
    std::shared_ptr<int> pSharedPtr1(new int(10));

    std::cout << *pSharedPtr1 << std::endl;

    std::shared_ptr<int> pSharedPtr2 = pSharedPtr1;
    std::cout << *pSharedPtr2 << std::endl;

    std::cout << *pSharedPtr2 << std::endl;

    system("pause");
    return 0;
}

程序的运行结果为:
10
10
10


3. weak_ptr

weak_ptr 可以指向 shared_ptr 指针指向的对象内存,却不拥有该内存。而使用 weak_ptr 成员 lock ,则可返回指向内存的一个 shared_ptr 对象,且所指向的内存无效时,返回空指针(nullptr)。

下面是一个简单的示例:

#include <iostream>
#include <memory>
#include <stdlib.h>

int main(int argc, char** argv)
{
    std::shared_ptr<int> pSharedPtr1(new int(10));
    std::shared_ptr<int> pSharedPtr2 = pSharedPtr1;
    std::weak_ptr<int> pWeakPtr = pSharedPtr2;

    std::shared_ptr<int> sp = pWeakPtr.lock();
    if (sp != nullptr)
        std::cout << *sp << std::endl;

    sp.reset();
    pSharedPtr1.reset();
    pSharedPtr2.reset();

    std::shared_ptr<int> sp2 = pWeakPtr.lock();
    if (sp2 != nullptr)
        std::cout << *sp2 << std::endl;

    system("pause");
    return 0;
}

结果为:
10

当调用

sp.reset();
pSharedPtr1.reset();
pSharedPtr2.reset();

时,其引用计数为0,资源被释放,所以在调用 std::shared_ptr sp2 = pWeakPtr.lock(); 时,返回的对象为 nullptr

不会飞的纸飞机
扫一扫二维码,了解我的更多动态。

下一篇文章:c++11学习笔记(7)- 智能指针的简单实现