For faster navigation, this Iframe is preloading the Wikiwand page for 智能指针.

智能指针

智慧指针(英语:Smart pointer)是一种抽象的数据类型。在程式设计中,它通常是经由类模板来实现,借由模板来达成泛型,借由类别的析构函数来达成自动释放指针所指向的存储器或物件。

C++中的智慧指针

auto_ptr

auto_ptr这个类模板被定义在ISO/IEC 14882的第20.4.5章节里:

namespace std {

    template <class Y> struct auto_ptr_ref {};

    template <class X>
    class auto_ptr {
    public:
        typedef X element_type;

        // 20.4.5.1 construct/copy/destroy:
        explicit           auto_ptr(X* p =0)throw();
                           auto_ptr(auto_ptr&)throw();
        template <class Y> auto_ptr(auto_ptr<Y>&)throw();

        auto_ptr&                      operator=(auto_ptr&)throw();
        template <class Y> auto_ptr&   operator=(auto_ptr<Y>&)throw();
        auto_ptr&                      operator=(auto_ptr_ref<X>)throw();

        ~auto_ptr() throw();

        // 20.4.5.2 members:
        X&     operator*() const throw();
        X*     operator->() const throw();
        X*     get() const throw();
        X*     release() throw();
        void   reset(X* p =0)throw();

        // 20.4.5.3 conversions:
        auto_ptr(auto_ptr_ref<X>)throw();
        template <class Y> operator auto_ptr_ref<Y>() throw();
        template <class Y> operator auto_ptr<Y>() throw();
    };

}

unique_ptr

C++11中提供了std::unique_ptr,定义在<memory>头文件中。

C++11新增了move语义,相比copy语义,它能更好的实现值传递.std::auto_ptr使用的是copy语义,为了向后兼容,C++11没有修改std::auto_ptr,而是引入了新的使用move语义的std::unique_ptr.

unique_ptr的拷贝构造函数和赋值运算符都声明为deleted,也就是说它不能被拷贝,只能通过std::move来转递它所指向的内存的所有权。

std::unique_ptr<int> p1(new int(5));
std::unique_ptr<int> p2 = p1; // 编译会出错
std::unique_ptr<int> p3 = std::move (p1); // 转移所有权,现在那块内存归p3所有, p1成为无效的指针。

p3.reset(); //释放内存。
p1.reset(); //实际上什么都没做。

std::auto_ptr依然存在,但在C++11中被标为"弃用".

shared_ptr和weak_ptr

基于Boost库, C++11加入了shared_ptrweak_ptr.它们最早在TR1中就被引入,但在C++11中,在Boost的基础上又加入了新的功能。

std::shared_ptr使用引用计数。每一个shared_ptr的拷贝都指向相同的内存。在最后一个shared_ptr析构的时候,内存才会被释放。

std::shared_ptr<int> p1(new int(5));
std::shared_ptr<int> p2 = p1; // 都指向同一内存。

p1.reset(); // 因为p2还在,所以内存没有释放。
p2.reset(); // 释放内存,因为没有shared_ptr指向那块内存了。

std::shared_ptr使用引用计数,所以有循环计数的问题。为了打破循环,可以使用std::weak_ptr.顾名思义, weak_ptr是一个弱引用,只引用,不计数。如果一块内存被shared_ptr和weak_ptr同时引用,当所有shared_ptr析构了之后,不管还有没有weak_ptr引用该内存,内存也会被释放。所以weak_ptr不保证它指向的内存一定是有效的,在使用之前需要检查。

std::shared_ptr<int> p1(new int(5));
std::weak_ptr<int> wp1 = p1; // 还是只有p1有所有权。

{
  std::shared_ptr<int> p2 = wp1.lock(); // p1和p2都有所有权
  if (p2) // 使用前需要检查
  { 
    // 使用p2
  }
} // p2析构了,现在只有p1有所有权。

p1.reset(); // 内存被释放。

std::shared_ptr<int> p3 = wp1.lock(); // 因为内存已经被释放了,所以得到的是空指针。
ifp3
{
  // 不会执行到这。
}

外部链接

{{bottomLinkPreText}} {{bottomLinkText}}
智能指针
Listen to this article

This browser is not supported by Wikiwand :(
Wikiwand requires a browser with modern capabilities in order to provide you with the best reading experience.
Please download and use one of the following browsers:

This article was just edited, click to reload
This article has been deleted on Wikipedia (Why?)

Back to homepage

Please click Add in the dialog above
Please click Allow in the top-left corner,
then click Install Now in the dialog
Please click Open in the download dialog,
then click Install
Please click the "Downloads" icon in the Safari toolbar, open the first download in the list,
then click Install
{{::$root.activation.text}}

Install Wikiwand

Install on Chrome Install on Firefox
Don't forget to rate us

Tell your friends about Wikiwand!

Gmail Facebook Twitter Link

Enjoying Wikiwand?

Tell your friends and spread the love:
Share on Gmail Share on Facebook Share on Twitter Share on Buffer

Our magic isn't perfect

You can help our automatic cover photo selection by reporting an unsuitable photo.

This photo is visually disturbing This photo is not a good choice

Thank you for helping!


Your input will affect cover photo selection, along with input from other users.

X

Get ready for Wikiwand 2.0 🎉! the new version arrives on September 1st! Don't want to wait?