Control Pointers – C++ Weekly EP3Bi li bibilibili

Why use Smart Pointer

Is the trouble of whether to free after new, memory leakage and other problems.

Auto e = STD ::make_unique

(). This is equivalent to new an Entity pointer.

Pass the exclusive pointer to e with STD ::move(e), and the bar function will own e. After the execution in BAR, E will be destroyed automatically, so there is no need to take the initiative to free.

unique_ptr

  • A pointer to an object cannot be assigned to a smart pointer.

  • The second sentence is true, but not recommended.

  • The third sentence is true and recommended

     unique_ptr <Entity> e1 = make_unique<Entity>();
    Copy the code
  • Change the former to auto

     auto e2 = make_unique<Entity>();
    Copy the code
  • Unique_ptr is a single ownpartnership, so an assignment cannot be made to it.

  • The sixth sentence is true. You can move. Move is equivalent to transfer ownership.

     unique_ptr<Entity> e2 = move(e1);
    Copy the code

    So:

    foo(move(e1)); // Then you can successfully pass the parameter.Copy the code

Here’s an example:

 #include <memory>
 #include <string>
 #include <iostream>
 #include <cstdio>
 using namespace std;
 ​
 class Entity{
 public:
     Entity() {puts("Entity created!"); } ~Entity(){puts("Entity destroyed!");}
 };
 ​
 void ex1(a){
     puts("-- -- -- -- -- -- -- --");
     puts("Entering ex1");
     {
         puts("Entering ex1::scope1");
         auto e1 = make_unique<Entity>();    // The Entity object is created here
         puts("Leaving ex1::scope1");
     }
     // When the scope ends, the object is destructed and the pointer is released
     puts("Leaving ex1");
 }
 ​
 void foo(unique_ptr<Entity>){
     puts("Entering foo");
     puts("Leaving foo");
 }
 ​
 void ex2(a){
     puts("-- -- -- -- -- -- -- --");
     puts("Entering ex2");
     auto e1 = make_unique<Entity>();    // The Entity object is created here
     foo(move(e1));
     // after executing foo, it is released
     puts("Leaving ex2");
 }
 ​
 ​
 int main(a)
 {
     ex1();
     ex2();
 }
Copy the code

As you can see, the unique_ptr lifecycle is released after its scope ends.

We can see that unique_ptr is exclusive, only one unique_ptr can occupy the object at a time, and then if we need to assign the value of the unique_Ptr, we need to use move to transfer. Then the life cycle is simply terminated when its scope ends. Move to func4, then func4 ends, release.

shared_ptr

The feature of shareD_ptr is that multiple share_Ptr can share the same object simultaneously. Like unique_ptr, it is automatically released at the end of its local scope, but because it can be shared multiple times, a reference count is maintained and deleted only when the count reaches zero.

  • This is perfect for multithreaded programs.

The usage is very similar to unique_ptr, the only difference being that it can be copied:

 share_ptr<Entity> e2 = e1;  
Copy the code

This completes a copy such that shared_ptr count+1.

Here’s an example:

  • Line38: A make_shared was created
  • Line42: copy a shared_ptr, so use_count +=1 becomes 2
  • Line44: e2passGiven e3,use_count stays the same,So e2 is useless. .
  • Line48: After leaving this scope, E3 is released, so use_count -= 1 becomes 0
  • Finally, E1 is also out of scope, so it self-destructs.

weak_ptr