C ++ smart pointer Precautions

  1. Do not use auto_ptr.

  2. unique_ptr can point to a dynamic array. Because unique_ptr have unique_ptr <T []> overloaded versions of dynamic objects destroyed when calling delete []:

    class A{};
    unique_ptr<A[]> unique_ap(new A[1]{A()});
    
  3. Use unique_ptr, when the need to share ownership of the object can still be converted to shared_ptr, but not vice versa.

    class A{};
    unique_ptr<A> a(new A("unique_ptr"));
    shared_ptr<A> b = move(a);
    //a = move(b);  // 报错
    //a.reset(b.get());  // 运行错误
    cout<<a.get()<<endl;
    
  4. Use shared_ptr need to consume more resources, shared_ptr thread needs to maintain a dynamic memory object reference points to a control block behind the counter and safe, which makes it more complicated than unique_ptr.

  5. Perhaps the shared object ownership is not your intention, but using shared_ptr may cause other programmers inadvertently modify your shared object by assigning it to another shared pointer.

  6. Do not use a smart pointer pointer initialize statically allocated objects, otherwise, when the smart pointer itself is revoked, it will attempt to delete a pointer to the non-dynamic allocation of objects, resulting in undefined behavior.

    A a();//全局变量
    
    int main() {
        A b();//局部变量
    	//unique_ptr<A> pa(&a); // 运行错误
        //unique_ptr<A> pa(&b); // 析构两次
    }
    
  7. unique_ptr as a function return values.

    Although no unique_ptr copy semantics, but the semantics provided a mobile, it is possible to function as a return value.

    class A{};
    unique_ptr<A> fun(){
    	unique_ptr<A> pa(new A());
    	return pa;
    }
    		
    int main() {
        auto pa = fun();
        return 0;
    }
    
  8. Prudent use of smart pointers get and release methods

    When returning a raw pointer using the get method, smart pointer to an object and does not release ownership, so we must be careful to use bare hands to avoid a crash.

    But returned by the unique_ptr.release () method bare hands, we ourselves need to delete delete the object, because after calling the release method, the unique_ptr no longer has ownership of the object.

  9. When the smart pointer with the pointer needs to bare with the use, the need to avoid the following:

    • Use naked pointer to initialize multiple smart pointers
    • Perform delete operations on smart pointers used bare hands

    The steps above will cause the program to try to destroy the object has been destroyed again, which causes the program to crash. So, when using bare hands to initialize a smart pointer, make sure bare hands should never be used again.

    class A{};
    A *pa = new A();
    unique_ptr<A> unique_pa(pa);
    //delete pa;  // 运行错误
    
    A *pb = new A();
    unique_ptr<A> unique_pb1(pb);
    //unique_ptr<A> unique_pb2(pb);  // 运行错误
    
  10. Shared_ptr get inside the object method must be used shared_from_this

    Inside the object you want to obtain a pointer to the object shared_ptr, can not be constructed using this pointer (see reason 3), while shared_from_this method must be used to ensure that all point to the same control block shared_ptr.

    Unused shared_from_this situation:

    class A{
    public:
        string id;
        A(string id):id(id){}
        shared_ptr<A> get_shared_ptr(){return shared_ptr<A>(this);}
        ~A(){}
    };
    
    int main() {
        shared_ptr<A> pa(new A("shared_ptr"));
    	//shared_ptr<A> pb = pa->get_shared_ptr(); // 运行错误
        return 0;
    }
    

    Use shared_from_this situation:

    class A : public enable_shared_from_this<A>{
    public:
        string id;
        A(string id):id(id){}
        shared_ptr<A> get_shared_ptr(){return shared_from_this();}
        ~A(){}
    };
    
    int main() {
        shared_ptr<A> pa(new A("shared_ptr"));
        shared_ptr<A> pb = pa->get_shared_ptr();
        return 0;
    }
    
  11. Use caution shared_from_this method.

    When you need to use shared_from_this method, you should note the following:

    Not be called in the constructor method shared_from_this following code, shared_ptr <A> shared_pa (new A ( "shared_ptr")) actually performs three actions:
    first calls the constructor enable_shared_from_this <A>;
    secondly call A constructor;
    and finally call the constructor of shared_ptr <A>. The third action is set enable_shared_from_this <A> of weak_ptr.

    In the class inheritance tree can not have two or more enable_shared_from_this

  12. Judge must call weak_ptr.lock () the effectiveness of shared_ptr acquired
    when by weak_ptr.lock () method to get the time shared_ptr, must determine whether the shared_ptr effective, because at this point we expect shared_ptr object may have been deleted.

    class A{
    public:
        string id;
        A(string id):id(id){cout<<id<<":构造函数"<<endl;}
        ~A(){cout<<id<<":析构函数"<<endl;}
    };
    
    int main() {
        weak_ptr<A> weak_pa;
        shared_ptr<A> shared_pa(new A("shared_ptr"));
        weak_pa = shared_pa;
        cout<<weak_pa.lock()<<endl;
        shared_pa.reset();
        cout<<weak_pa.lock()<<endl;
        return 0;
    }
    

    The output is:

    shared_ptr:构造函数
    0xfd11c8
    shared_ptr:析构函数
    0
    
  13. Try to make use of the function to initialize a smart pointer

    And using make_unique make_shared initialization unique_ptr shared_ptr and have the advantage (see particularly "smart pointer with the make_unique make_shared"):

    • More efficient
      when creating a shared_ptr with new to create an object at the same time, then dynamically allocate memory occurs twice: once using the new application to the object itself, and once it is triggered by the constructor for shared_ptr is resource management object allocation.

      When using the make_shared, C ++ compilers only a one-time allocation of a large enough memory to save the resource managers and the new object.

    • Exception safety
      Since C ++ does not guarantee the order of evaluation function arguments, wherein one argument if the value is the right new smart pointers initialized, abnormality may be due to memory leak.

    • Derived automatically use auto type.

  14. When using a dynamic array shared_ptr point, you must use a custom Deleter, if no custom Deleter, shared_ptr only when the memory is released outside the scope pointer points to the object, the first element of the array, where the array of memory elements other not release caused by a memory leak.

    class A{};
    shared_ptr<A> a(new A[2]{A(),A()},[](A *a){delete []a;});
    
  15. Shared_ptr should be used to avoid circular references.

  16. share_ptr type conversions can not use C ++ common transformation function.

    share_ptr casts can not use conventional C ++ transformation functions, i.e. static_cast, dynamic_cast, const_cast, but to use static_pointer_cast, dynamic_pointer_cast, const_pointer_cast.

  17. shared_ptr is not thread-safe guarantee shared object.

Published 253 original articles · won praise 13 · views 60000 +

Guess you like

Origin blog.csdn.net/LU_ZHAO/article/details/105113241