• 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 << '
    ';
  • 相关阅读:
    springboot整合mybatis采用druid连接池对mysql,hive双数据源整合并打包
    csv数据导入kudu
    Hive数据导入导出的几种方式
    【纪中受难记】——Day20:祈祷落幕时
    2017第八届蓝桥杯C/C++ B组省赛 —— 第三题:承压计算
    2017第八届蓝桥杯C/C++ B组省赛 —— 第一题:购物单
    2017第八届蓝桥杯C/C++ B组省赛 —— 第一题:购物单
    位运算的奇巧淫技
    位运算的奇巧淫技
    数据结构和算法 —— 图
  • 原文地址:https://www.cnblogs.com/y4247464/p/13816322.html
Copyright © 2020-2023  润新知