关闭

C++ unique_ptr

标签: C++ STLC++
237人阅读 评论(0) 收藏 举报
分类:
        std::unique_ptr属于STL库,它的作用和auto_ptr相似,也是管理一个对象指针,提供一个释放内存的封装操作。
        顾名思义,std::unique_ptr独有对象指针的管理权,不会允许其他unique_ptr再来分享了,这是和std::auto_ptr最大的区别了,也是比auto_ptr优越的地方了。
        std::auto_ptr有两个成员变量(Template parameters):
        1.管理对象的指针。
        2.内存回收对象(callable object used as deleter)。默认为default_delete。

        std::uniqur_ptr的构造函数有多个:
default (1)
constexpr unique_ptr() noexcept;
from null pointer (2)
constexpr unique_ptr (nullptr_t) noexcept : unique_ptr() {}
from pointer (3)
explicit unique_ptr (pointer p) noexcept;
from pointer + lvalue deleter (4)
unique_ptr (pointer p,
    typename conditional<is_reference<D>::value,D,const D&> del) noexcept;
from pointer + rvalue deleter (5)
unique_ptr (pointer p,
    typename remove_reference<D>::type&& del) noexcept;
move (6)
unique_ptr (unique_ptr&& x) noexcept;
move-cast (7)
template <class U, class E>
  unique_ptr (unique_ptr<U,E>&& x) noexcept;
move from auto_ptr (8)
template <class U>
  unique_ptr (auto_ptr<U>&& x) noexcept;
copy (deleted!) (9)
unique_ptr (const unique_ptr&) = delete;

        可以指定构造对象,同时支持move构造:

        std::unique_ptr<int> GetVal()
        {
             std::unique_ptr<int> pLocalValue(new int(10));

            return pLocalValue;
        }

        int main()
        {
            std::unique_ptr<int> pMoveConstruct = GetVal();

            return 0;
        }


         但是它不支持拷贝构造,所以就不会出现像std::auto_ptr那么容易的所有权转移问题了。
std::unique_ptr同样会出现同时持有同一对象指针的所有权问题:
         int* pTemp = new int();

         std::unique_ptr<int> p1(pTemp);
         std::unique_ptr<int> p2(pTemp);

所以也要保证"防止两个unique_ptr拥有一个对象"。
        std::unique_ptr不支持拷贝构造,所以不能直接作为容器元素,但是我们可以通过move构造来创建容器元素:
    std::unique_ptr<int> pTemp(new int());
    std::vector < std::unique_ptr<int> > vecTest;
    vecTest.push_back(std::move(pTemp));

        
        同时,std::unique_ptr重载了=操作符:
move assignment (1)
unique_ptr& operator= (unique_ptr&& x) noexcept;
assign null pointer (2)
unique_ptr& operator= (nullptr_t) noexcept;
type-cast assignment (3)
template <class U, class E>
  unique_ptr& operator= (unique_ptr<U,E>&& x) noexcept;
copy assignment (deleted!) (4)
unique_ptr& operator= (const unique_ptr&) = delete;
我们可以看到,同样的只支持move赋值:
        std::unique_ptr<int> pTest1(new int());
        std::unique_ptr<int> pTest2 = std::move(pTest1);

另外还有operator bool操作符,它实现了和指针同样的操作,可以直接当做bool来进行指针的判断:
         std::unique_ptr<int> pTest1(new int());
         if (pTest1) //do sth

        std::unique_ptr和std::auto_ptr的另外一个区别就是可以管理数组,同时也实现了operator[]:
         std::unique_ptr<int[]> pTest1(new int[10]);
         for (int i = 0; i < 10; ++i)
         {
            pTest1[i] = 10;
         }

        我们和std::auto_ptr来对比的话可以发现std::unique_ptr和std::auto_ptr非常的相似,但是unique_ptr不能随随便便的转移所有权,必须通过move来转移,这样对于语意理解有莫大的好处,也不会存在莫名其妙感了。

  2016-10-09:
今天在使用unique_ptr的时候发现一个问题,因为看到有一个release的成员方法,就想当然的认为是释放持有指针的内存,但实际发现析构函数怎么都进不去,重新看文档发现只是释放了所有权并且返回所持有对象的指针。
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:11639次
    • 积分:265
    • 等级:
    • 排名:千里之外
    • 原创:15篇
    • 转载:2篇
    • 译文:0篇
    • 评论:4条
    文章分类
    最新评论