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 << '
    ';
  • 相关阅读:
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    chrome标签记录——关于各类性能优化
    JavaScript(二)——在 V8 引擎中书写最优代码
    JavaScript学习(一)——引擎,运行时,调用堆栈
    MySQL数据库操作生成UUID
    使用Spring MVC实现文件上传与下载
    敏捷过程(小规模团队敏捷开发)
    后台获取日期值,前台Js对日期进行操作
    搭建Spring相关框架后,配置信息文件头部出现红色小×错误。
  • 原文地址:https://www.cnblogs.com/y4247464/p/13816322.html
Copyright © 2011-2022 走看看