zoukankan      html  css  js  c++  java
  • C++11智能指针

    Smart Pointers - What, Why, Which?  http://ootips.org/yonat/4dev/smart-pointers.html

    auto_ptr

      C++98中,智能指针通过一个模板类型auto_ptr实现,缺点:拷贝时返回一个左值,不能调用delete[](只能针对单个对象使用,不能针对数组使用),所以在C++11标志中被废弃了。

      auto_ptr的一种实现方式,可以看到在析构函数中调用的是:delete ptr;

      C++11标志引入了:unique_ptr、shared_ptr、weak_ptr来自动回收堆分配的对象。

    unique_ptr

      如何自己实现:https://www.jianshu.com/p/77c2988be336

      与所指定对象的内存绑定紧密,不能与其他unique_ptr类型的指针对象共享所指对象的内存,每个unique_ptr都是唯一地拥有指向对象的内存。可通过std::move函数来转移所指对象内存的所有权,在通过move函数转移后,原来的unique_ptr不在拥有内存,再通过该指针指向内存会导致运行时错误。

      可通过调用reset()函数来显示释放内存。

    注意:

      当该智能指针被销毁、通过=操作符(an assignment operation)修改该智能指针指向的对象,或显示地通过reset函数修改指向的对象后,智能指针指向的对象会被销毁。

    成员函数:

    • get

      return the stored pointer,返回存储的指针,The stored pointer to the object managed by the unique_ptr, if any, or to nullptr if the unique_ptr is empty.调用该函数并不会使得unique_ptr失去所指向对象的所有权。

    • get_deleter

      return the stored deleter,获取存储的删除器,The stored deleter is a callable object.deleter用于当unique_ptr在析构、被分配一个新值,或reset函数调用时自动调用,用于删除所指向的对象。

    • operator=

      check if not empty,判断一个unique_ptr当前是否拥有一个对象,如果unique_ptr是empty,返回false;其他情况返回true

    // example of unique_ptr::operator bool
    #include <iostream>
    #include <memory>
    
    
    int main () {
      std::unique_ptr<int> foo;
      std::unique_ptr<int> bar (new int(12));
    
      if (foo) std::cout << "foo points to " << *foo << '
    ';
      else std::cout << "foo is empty
    ";
    
      if (bar) std::cout << "bar points to " << *bar << '
    ';
      else std::cout << "bar is empty
    ";
    
      return 0;
    }
    • release:

      Releases ownership of its stored pointer, by returning its value and replacing it with a null pointer.This call does not destroy the managed object, but the unique_ptr object is released from the responsibility of deleting the object. Some other entity must take responsibility for deleting the object at some point.

      也就是说:调用release函数只是让unique_ptr放弃对所指向对象的所有权,但是并不会析构所指向对象,需要其他的方式来释放所指向对象的内存。

    • reset

      void reset (pointer p = pointer()) noexcept;

      析构当前unique_ptr所指向的对象,并获取p指针的所有权。如果p是一个null pointer,unique_ptr会成为empty,在函数调用后不再拥有任何对象。如果想要释放unique_ptr对对象的所有权但是不析构所指向的对象,使用release函数。

    • swap
    void swap (unique_ptr& x) noexcept;
    Exchanges the contents of the unique_ptr object with those of x, transferring ownership of any managed object between them without destroying either.
    The function swaps the respective stored pointers and stored deleters by invoking swap on them.
    // unique_ptr::swap example
    #include <iostream>
    #include <memory>
    
    int main () {
      std::unique_ptr<int> foo (new int(10));
      std::unique_ptr<int> bar (new int(20));
    
      foo.swap(bar);
    
      std::cout << "foo: " << *foo << '
    ';
      std::cout << "bar: " << *bar << '
    ';
    
      return 0;
    }
    • operator*

      return a reference to the managed object.返回一个指向所管理对象的引用。

    • operator->

      return a pointer to the managed object in order to access one of its members.获取一个指向所管理对象的指针,用于访问其成员。

    shared_ptr

      Manages the storage of a pointer, providing a limited garbage-collection facility, possibly sharing that management with other objects.

      与其他的shared_ptr共同拥有指向某对象的所有权,当最后一个指向该对象的shared_ptr结束生命周期时才会调用析构函数释放所指向对象的内存。只有通过拷贝shared_ptr才会共享所有权。如果两个shared_ptr通过构造函数创建的,即使构造它们的是同一个对象,它们也不会共享所有权,这就会导致风险,因为可能一个shared_ptr已经释放了内存,而另外一个此时再访问就会导致错误。

      另外,shared_ptr对象可以在共享一个指针的所有权的同时,指向另一个对象。该功能成为aliasing(见构造函数:http://www.cplusplus.com/reference/memory/shared_ptr/shared_ptr/),通常用于在拥有对象的所有权的同时指向对象的成员。由于该功能的存在,一个shared_ptr可能与两个指针相关联:

    • stored pointer, which is the pointer it is said to point to, and the one it dereferences with operator*.  shared_ptr在调用operator*获取到的。
    • An owned pointer (possibly shared), which is the pointer the ownership group is in charge of deleting at some point, and for which it counts as a use. 与其他shared_ptr共享的指针,并负责该对象的析构。

      通常情况下,shared_ptr的stored pointer和owned pointer指向同一个对象,但是alias shared_ptr对象(those constructed with the alias constructor and their copies)可能指向不同的对象。

      一个不拥有任何指针所有权的shared_ptr是一个空(empty)shared_ptr。一个不指向任何对象的shared_ptr是一个null shared_ptr。注意两者不相等。

    成员函数:

    • use_count

      返回共享shared_ptr对象指向同一对象的数量

    • unique

      Returns whether the shared_ptr object does not share ownership over its pointer with other shared_ptr objects (i.e., it is unique).

    weak_ptr

      weak_ptr可以指向内存的一个shared_ptr对象,却不拥有该内存。使用weak_ptr的成员函数lock,可以返回其指向内存的一个shared_ptr,且在所指向对象内存已经无效时,返回nullptr。这可以验证shared_ptr智能指针的有效性。

    #include <memory>
    void check(weak_ptr<int>& wp)
    {
        shared_ptr<int> sp = wp.lock();//转换为shared_ptr
        if (sp != nullptr)
        {
            cout << "still " << *sp << endl;
        }
        else
        {
            cout << "pointer is invalid" << endl;
        }
    }
    
    
    int main(int argc, char *argv[])
    {
        //weak-ptr=====
        shared_ptr<int> sp1(new int(22));
        shared_ptr<int> sp2 = sp1;    //使用拷贝构造,共享所有权
        weak_ptr<int> wp = sp1;    //指向shared_ptr<int>所指对象
    
        cout << *sp1 << endl;
        cout << *sp2 << endl;
        check(wp);
    
        sp1.reset();
        cout << *sp2 << endl;
        check(wp);
    
        sp2.reset();
        check(wp);

    输出:

  • 相关阅读:
    338. Counting Bits
    78. Subsets
    MySQL读写分离
    AESEncryption Aes 加密
    LoopBox 用于包装循环的盒子
    ES 服务器 索引、类型仓库基类 BaseESStorage
    一键压缩脚本
    非常好用的一个分组扩展方法
    快递、拆分、合并、优选逻辑
    Git Extensions 使用小结
  • 原文地址:https://www.cnblogs.com/zyk1113/p/13474149.html
Copyright © 2011-2022 走看看