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

    Smart Pointer

    std::unique_ptr - single ownership 

    std::shared_ptr - shared ownership

    std::weak_ptr - temp / no ownership 


    为什么使用智能指针?

    void bar(Entity* e) {
        // who owns e?
        // How long is e's life cycle?
        // Should I delete e?
    }
    
    void foo() {
        Entity* e = new Entity();
        e->DoSomething();
        bar(e);
    }
    
    foo();
    // out of scope, memory leak
    void bar(std::unique_ptr<Entity> e) {
        // bar owns e
        // e will be automatically destoryed
    }
    
    void foo() {
        auto e = std::unique_ptr<Entity>();
        e->DoSomething();
        bar(std::move(e));
    }
    
    foo();
    // no memory leak

    1、创建unique_ptr

    1 std::unique_ptr<Entity> e1 = new Entity();   //non-assignable
    2 std::unique_ptr<Entity> e1(new Entity());    //OK
    3 std::unique_ptr<Entity> e1 = std::make_unique<Entity>();  //preferred
    4 auto e2 = std::make_unique<Entity>();  //preferred
    5 std::unique_ptr<Entity> e2 = e1;       //non-copyable
    6 std::unique_ptr<Entity> e2 = std::move(e1);  //moveable, transfer ownership
    7 foo(std::move(e1));   //transfer ownership

    Example:

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <memory>
     4 #include <string>
     5 
     6 using namespace std;
     7 
     8 class Entity {
     9    public:
    10     Entity() { puts("Entity created!"); }
    11     ~Entity() { puts("Entity destoried!"); }
    12 };
    13 
    14 void ex1() {
    15     puts("------------");
    16     puts("Entering ex1");
    17     {
    18         puts("Entering ex1::scope1");
    19         auto e1 = make_unique<Entity>();
    20         puts("Leaveing ex1::scope1");
    21     }
    22     puts("Entering ex1");
    23 }
    24 
    25 void foo(unique_ptr<Entity>) {
    26     puts("Entering foo");
    27     puts("leaving  foo");
    28 }
    29 
    30 void ex2() {
    31     puts("------------");
    32     puts("Entering ex2");
    33     auto e1 = make_unique<Entity>();
    34     foo(move(e1));
    35     // e1 was destoried.
    36     puts("Leaving ex2");
    37 }
    38 
    39 int main(int argc, char const *argv[]) {
    40     ex1();
    41     ex2();
    42     return 0;
    43 }

     2、unique_ptr的生命周期

     

    创建shared_ptr

    1 std::shared_ptr<Entity> e1 = std::make_shared<Entity>();  // preferred
    2 std::shared_ptr<Entity> e1(new Entity());                 // OK
    3 auto e1 = std::make_shared<Entity>();                     // preferred
    4 std::shared_ptr<Entity> e2 = e1;             // copyable,use_count+1
    5 std::shared_ptr<Entity> e2 = std::move(e1);  // moveable, use_count remains
    6 foo(std::move(e1));                          // use_count remains
    7 foo(e1);                                     // use_count+1

    example:

    #include <cstdio>
    #include <iostream>
    #include <memory>
    #include <string>
    
    using namespace std;
    
    class Entity {
       public:
        Entity() { puts("Entity created!"); }
        ~Entity() { puts("Entity destoried!"); }
    };
    
    oid ex3() {
        puts("-------------");
        puts("Entering ex3");
        auto e1 = make_shared<Entity>();
        cout << e1.use_count() << endl;
        {
            puts("Entering ex3::scope1");
            auto e2 = e1;
            cout << e1.use_count() << endl;
            auto e3 = move(e2);
            cout << e1.use_count() << endl;
            puts("Leaving ex3:scope1");
        }
        cout << e1.use_count() << endl;
        puts("Leaving ex3");
    }
    
    int main(int argc, char const *argv[]) {
        // ex1();
        // ex2();
        ex3();
        return 0;
    }

    out:

     shared_ptr的生命周期

     在fun1中创建了shared_ptr,transfer给fun2后引用计数还是1,在func2中用多线程调用了fun3,fun4,fun5,shared给它们

    小结:

    1.尽量使用智能指针而不是裸指针

    2.优先使用unique_ptr

    unique_ptr

    正常情况下分配与释放动态内存:

    #include <iostream>
    #include <memory>
    #include <string>
    
    using namespace std;
    
    int main(void) 
    {
         string *str = new(string("hello world"));
         delete str;   //需要手动去释放
       return 0; }

    使用智能指针unique_ptr

    unique_ptr<string> pointer(new string("hello world"));  
    // pointer是一个栈变量,在栈变量被回收后动态内存也会被回收
    cout << *pointer << '
    ';
  • 相关阅读:
    HTML5 API分享
    承接VR外包,虚拟现实外包,北京正规公司
    虚拟现实外包—动点飞扬软件专门承接VR/AR场景、游戏、项目外包
    Unity3d外包—就找北京动点软件(长年承接Unity3d软件、游戏项目外包)
    Kinect外包团队— 2016中国VR开发者论坛第一期
    Kinect外包-就找北京动点飞扬软件(长年承接微软Kinect体感项目外包,有大型Kinect案例)
    Win10外包公司(长年承接Win10App外包、Win10通用应用外包)
    HTML5外包注意事项-开发HTML5游戏的九大坑与解决方法剖析
    HTML5外包团队:HTML5 Canvas使用教程
    libgo 2.0发布
  • 原文地址:https://www.cnblogs.com/y4247464/p/13816322.html
Copyright © 2011-2022 走看看