C + + smart pointer

Time:2020-10-25

Introduction of C + + 11 intelligent pointer

Smart pointer is mainly used to manage the memory allocated on the heap. It encapsulates the ordinary pointer into a stack object. When the stack object’s lifetime is over, the requested memory will be released in the destructor to prevent memory leakage.

Why use smart pointers

The function of smart pointer is to manage a pointer, because there are the following situations: the requested space is forgotten to be released at the end of the function, resulting in a memory leak. Using smart pointers can largely avoid this problem, becauseAn intelligent pointer is a class. When it exceeds the scope of a class, the class will automatically call the destructor, and the destructor will automatically release resources。 So the principle of smart pointer isAt the end of the function, the memory space will be released automatically, and there is no need to release the memory space manually

The smart pointer is defined in memory (non memory. H) with the namespace STD

unique_ptr

unique_ PTR is auto which is used to replace c + + 98_ Products of PTR

unique_ptr An exclusive object can only have one unique at a time_ PTR points to the given objectIt is defined in memory (non memory. H) with the namespace STD

  • 1.unique_ PTR is not allowed to copy assignments and always keeps a unique value_ PTR manages an object.
  • 2.unique_ Although PTR cannot be assigned a value, the ownership of the object can be transferred through the function move(). Once moved (), the original up1 is no longer valid.
  • 3. Reset() can make unique_ PTR releases the pointer in advance.

auto_ptr

(c + + 98, C + + 11 has been abandoned) adopt the ownership mode.
auto_ PTR is suitable for managing dynamic objects with short life cycle or not to be transmitted over long distance. It is better to be limited within a function or within a class

Because of Auto_ PTR is based on exclusive ownership mode: two pointers cannot point to the same resource, and copying or assigning will change the ownership of the resource.

#include <iostream>
#include <memory>

class Test
{
public:
    void print()
    {
        std::cout << "Test::Print" << std::endl;
    }
};

int main()
{
    std::auto_ptr<Test> pTest1(new Test);
    pTest1->print();

    std::auto_ PTR < test > ptest2 (ptest1); // copy constructor
    pTest2->print();

    std::cout << "pTest1 pointer:" << pTest1.get() << std::endl;    //auto_ The member function get() of the PTR class returns an original pointer
    std::cout << "pTest2 pointer:" << pTest2.get() << std::endl;

    return 0;
}

//Print results:
Test::Print
Test::Print
pTest1 pointer:00000000
pTest2 pointer:01659548

//After replication construction, the ownership of the resource ptest1 points to is transferred to ptest2, while ptest1 becomes empty, and the two cannot share the resource at the same time.

auto_ There are two main problems in PTR

  • Copying and assigning can change the ownership of resources, which is not intuitive.
  • Auto cannot be used in STL container_ PTR, because the elements in the container must support copy constructable and assignable.

shared_ PTR (new intelligent pointer in C + + 11)

Based on the reference counting model. Resources can be shared by multiple pointers. It uses a counting mechanism to indicate that resources are shared by several pointers.

Every time there are shared_ When PTR objects point to resources, the reference counter is increased by 1; when there is shared_ When the PTR object is destructed, the counter is subtracted by 1; when the counter value is 0, the resource pointed to will be released. And the pointer of this type can be copied and assigned, that is, it can be used in STL container. In addition, shared_ PTR pointers can be used with polymorphic and incomplete types.

std::shared_ The PTR smart pointer shares the resource (ownership) it points to, that is, several shared_ PTR can have an object at the same time, and share a constrol block, which contains the shared pointing to the resource_ The number of PTR objects, weak pointing to resources_ The number of PTR objects and delegators (delete: a user-defined function used to release resources, which can be omitted by default).

An empty shared_ The PTR object does not own any resources and control blocks. On the other hand, a shared_ PTR is initialized to a null pointer and a control block, which is different from empty shared_ ptr。 When the shared reference counter is 0, the resource is released (either by the delete operator or by a user supplied delete).

#include <iostream>
#include <memory>

class Test
{
public:
    void print()
    {
        std::cout << "Test::Print" << std::endl;
    }
};

int main()
{
    std::shared_ptr<Test> pTest1(new Test);
    pTest1->print();

    std::shared_ PTR < test > ptest2 (ptest1); // copy constructor
    pTest2->print();

    std::cout << "pTest1 pointer:" << pTest1.get() << std::endl;    //shared_ The member function get() of the PTR class returns an original pointer
    std::cout << "pTest2 pointer:" << pTest2.get() << std::endl;

    std::cout << "count pTest1:" << pTest1.use_ count() << std::endl; //shared_ The member function of PTR class use_ Count(): returns how many smart pointers point to an object, mainly for debugging.
    std::cout << "count pTest2:" << pTest2.use_count() << std::endl;


    return 0;
}

//Print results:
Test::Print
Test::Print
pTest1 pointer:00C29550
pTest2 pointer:00C29550
count pTest1:2
count pTest2:2

//After ptest2 is created, ptest1's ownership of the resource is not deprived, but both ptest1 and ptest2 point to the resource, and the reference count of the resource is 2. When two shards\_ When PTR pointers ptest1 and ptest2 exceed their scope, the last destructed pointer will cause the resource to be released (because the reference count is 0).

shared_ The use of PTR

To be added…

Main disadvantages:

shared_ If PTRs refer to each other, the reference count of these two pointers can never drop to 0 and the resource will never be released.

The circular reference cannot be detected, which can cause the resource not to be released, resulting in a memory leak.

To solve the fix problem, C + + 11 introduces another smart pointer: weak_ PTR

weak_ PTR (new intelligent pointer in C + + 11)

weak_ Working principle of PTR

weak_ PTR is used to solve shared problems_ The deadlock problem when PTRs refer to each other_ If PTRs refer to each other, the reference count of these two pointers can never drop to 0 and the resource will never be released. It is a weak reference to an object and does not increase the reference count and shared of the object_ PTRs can be transformed into each other_ PTR can be directly assigned to it, and it can obtain shared by calling the lock function_ ptr。

The role is to assist shared_ PTR work can obtain the observation right of resources and observe the use of resources like bystanders. Observer means weak_ PTR only applies to shared_ PTR references without changing its reference count when the observed shared_ After failure, the corresponding wepak_ PTR also failed.

weak_ PTR is more like shared_ PTR assistant:

  • 1. Unlike the other three, it can allocate object memory directly through the constructor; it must use shared_ PTR to share memory.
  • 2. The lack of overloading opreator * and the – > operators means that even if it is assigned to an object, it cannot be used
  • 3. Does not actively participate in reference counting, that is, share_ PTR is released, so weak_ The objects stored in PTR are also released.
  • 4. Using the member function use_ Count() can view the current reference count, and expired() can determine whether the reference count is empty.
  • 5. The lock() function returns a shared_ PTR smart pointer: let weak_ PTR observation shared_ PTR smart pointer, and return a shared through lock function when necessary_ ptr。

weak_ PTR usage

To be added…