This article mainly introduces boost The use of intelligent pointer in .

    Memory management is a complicated problem ,C++ There are two implementations in : Garbage collection mechanism and intelligent pointer . The garbage collection mechanism is not affected by performance and other reasons C++ They are highly praised by the big men ,
And smart pointers are considered to be the solution C++ The optimal scheme of memory problem .

1. definition

     A smart pointer is a C++ Object of , The object behaves like a pointer , But it can be automatically deleted when it is not needed . Pay attention to this “ When it's not needed ”,
This is not a precise definition . This can refer to many aspects when it is not needed : Local variable exit function scope , Class is destructed ……. therefore boost Different intelligent pointers are defined to manage different scenarios .

shared_ptr<T> An internal reference counter is maintained to determine whether the pointer needs to be released . yes boost The most commonly used smart pointer in .
scoped_ptr<t> When the scope of this pointer disappears, it is released automatically
intrusive_ptr<T> A reference counter is also maintained , than shared_ptr Better performance . But the requirements T Provide this counter yourself .
weak_ptr<T> Weak pointer , To make peace with shared_ptr Combined use
shared_array<T> and shared_ptr be similar , But the access is an array
scoped_array<T> and scoped_ptr be similar , But the access is an array
2. Boost::scoped_ptr<T>

    scoped_ptr yes boost The simplest intelligent pointer in .scoped_ptr It's also very simple ,
When a pointer leaves its scope , Release related resources . Special attention must be paid to scoped_ptr
Ownership of pointers cannot be shared or transferred . In other words, this memory address can only be used for the declared variables , It can't be used for other purposes .

    Here is scoped_ptr Several characteristics of :

* scoped_ptr The efficiency and space consumption of the built-in pointer is almost the same .
* scoped_ptr Cannot be used on containers in standard libraries .( use shared_ptr replace )
* scoped_ptr Cannot point to an area of memory that can grow dynamically ( use scoped_array replace )

<> 1 class test
2 {
3 public:
4 void print()
5 {
6 cout << "test print now" <<endl;
7 }
8 };
9 int _tmain(int argc, _TCHAR* argv[])
10 {
11 boost::scoped_ptr<test> x(new test);
12 x->print();
13 return 0;
14 } <>


    shared_ptr It has the following characteristics :

* Maintain a reference counter internally , When a pointer points to this memory area, it is a reference count +1, conversely -1, If there is no pointer to this area , The reference counter is 0, Free memory area .
* Ownership can be shared and transferred .
* Can be used by containers in the standard library
* Cannot point to a dynamically growing block of memory ( use share_array replace )
We can take a look at the following examples :

<> 1 int _tmain(int argc, _TCHAR* argv[])
2 {
3 boost::shared_ptr<test> ptr_1(new test);
4 ptr_1->print();// The reference count is 1
5 boost::shared_ptr<test> ptr_2 = ptr_1;
6 ptr_2->print();// The reference count is 2
7 ptr_1->print();// Reference count is still 2
8 return 0;
9 } <>

4. Boost::intrusive_ptr<T>

    intrusive_ptr Main and share_ptr equally , contrast share_ptr, It's more efficient , But you need to maintain a reference counter yourself .

shared_ptr It provides more perfect function than ordinary pointer . There is a small price , A shared pointer takes up more space than a normal pointer , Each object has a shared pointer , This pointer has a reference counter for easy release . But for most of the reality , These are negligible .intrusive_ptr
Provides a compromise solution . It provides a lightweight reference counter , But the object itself must already have an object reference counter . It's not a bad idea , When you design your own classes, implement the same work as smart pointers , Then a reference counter must have been defined , This requires less memory , And it can improve execution performance . If you want to use intrusive_ptr
Pointing type T, Then you need to define two functions :intrusive_ptr_add_ref
and intrusive_ptr_release. Here is a simple example of how to implement it in your own class :

#include "boost/intrusive_ptr.hpp" // forward declarations class CRefCounted;
namespace boost { void intrusive_ptr_add_ref(CRefCounted * p); void
intrusive_ptr_release(CRefCounted * p); }; // My Class class CRefCounted {
private: long references; friend void
::boost::intrusive_ptr_add_ref(CRefCounted * p); friend void
::boost::intrusive_ptr_release(CRefCounted * p); public: CRefCounted() :
references(0) {} // initialize references to 0 }; // class specific
addref/release implementation // the two function overloads must be in the
boost namespace on most compilers: namespace boost { inline void
intrusive_ptr_add_ref(CRefCounted * p) { // increment reference count of object
*p ++(p->references); } inline void intrusive_ptr_release(CRefCounted * p) { //
decrement reference count, and delete object when reference count reaches 0 if
(--(p->references) == 0) delete p; } } // namespace boost

  This is the simplest ( Non thread safe ) Implement the operation . But as a general operation , It might be useful to provide a base class to do this , Maybe it will be introduced in other places .        

5. Boost::weak_ptr<T>


Comparison of strong reference and weak reference :

A strong reference when the referenced object is alive , This reference also exists ( That is to say , When there is at least one strong reference , Then the object cannot be released ).boost::share_ptr It's a strong reference . Relatively speaking , Weak references do not necessarily exist when the referenced object is alive . It's just a reference when it exists .

Is a smart pointer to execute a weak reference . When you need it, you can use a strong ( share ) The pointer points to it ( When the object is released , It is empty ), Of course, this strong pointer should be released immediately after use , In the example above, we can change it to a weak pointer .

struct CBetterChild : public CSample { weak_ptr<CDad> myDad; void BringBeer()
{ shared_ptr<CDad> strongDad = myDad.lock(); // request a strong pointer if
(strongDad) // is the object still alive? strongDad->SetBeer(); // strongDad is
released when it goes out of scope. // the object retains the weak pointer } };
    weak_ptr It's a weak pointer .weak_ptr cover shared_ptr control ,
It can pass through share_ptr Or lock Member functions are converted to share_ptr.

    weak_ptr One of the biggest features of is that it shares a share_ptr Memory for , But whether it is a structure or a structure weak_ptr Does not affect the reference counter .

<> 1 int _tmain(int argc, _TCHAR* argv[])
2 {
3 boost::shared_ptr<test> sharePtr(new test);;
4 boost::weak_ptr<test> weakPtr(sharePtr);
5 //weakPtr Is used to save the pointer to this memory area
6 // A lot of other things
7 boost::shared_ptr<test> sharePtr_2 = weakPtr.lock();
8 if (sharePtr_2)
9 sharePtr_2->print();
10 return 0;
11 } <>

6. Boost::shared_array<T> and Boost::scoped_array<T>

    As mentioned earlier shared_ptr and scoped_ptr Memory cannot be used for arrays (new
[]), therefore shared_array and scoped_array It's their substitute . We can take a look shared_array Usage of

<> 1 int _tmain(int argc, _TCHAR* argv[])
2 {
3 const int size = 10;
4 boost::shared_array<test> a(new test[]);
5 for (int i = 0; i < size; ++i)
6 a[i].print();
7 return 0;
8 } <>

7. Several points for attention in using intelligent pointer

    Here are a few points to pay attention to when using smart pointers :

* When declaring a smart pointer, instantiate it immediately , And it must not be released manually .
* …_ptr<T> no T* type . therefore :
                a: When you make a statement …_ptr<T> instead of ….._ptr<T*>

                b: Can't put T* The pointer of type is assigned to it

                c: Can't write ptr=NULl, And use ptr.reset() replace .

* You can't recycle references .
* Don't declare temporary share_ptr, Then pass the pointer to a function
8. summary

    Smart pointer is relatively simple to use , And it can be solved more effectively C++ Memory leaks , Use it C++ Let's use our children's shoes .

©2019-2020 Toolsou All rights reserved,
Error summary -myBatis plus paging use easyPOI Import Excel data In the problem of target detection “ recall Recall”,“ Accuracy Precision”vue use vue-clipboard2 Realize the function of copy link C In language switch sentence Wechat applet (uni-app)url Parameter transfer object hive compress &&hdfs Merge small files hive Summary of processing methods for a large number of small files use spring Of AntPathMatcher matching url route Linux Page replacement algorithm C Language implementation