C + + smart pointer

Posted by bhavesh on Mon, 17 Jan 2022 15:21:26 +0100

brief introduction

C++11 smart pointer

preface

1, What is a smart pointer?

shared_ptr strong intelligent pointer, which can change the reference count of resources
weak_ptr is a weak smart pointer and does not change the reference count of resources
unique_ptr exclusive smart pointer, which can only be transferred and cannot be assigned

2, Principle of intelligent pointer

shared_ptr uses a reference counter to allow multiple pointers to point to the same object. Every shared_ptr copies all point to the same memory, and jointly maintain the same reference counter to record the number of times the same instance is referenced. Each time it is used, the internal reference count is increased by 1. Each time it is destructed, the internal reference count is reduced by 1. When it is reduced to 0, the heap memory pointed to is automatically deleted. shared_ The reference count inside PTR is thread safe, but the reading of objects needs to be locked.

3, What is a smart pointer circular reference?

1. No circular reference

1.1 the codes are as follows:

#include<iostream>
#include<string>
#include<memory>
using namespace std;
class BTest;
class ATest
{
public:
	ATest(){
		cout << "ATest Successfully constructed!" << endl;
	}
	~ATest(){
		cout << "ATest Deconstruction succeeded!" << endl;
	}
public:
	shared_ptr<B> m_bptr;     //quote
};

class BTest
{
public:
	BTest(){
		cout << "BTest Successfully constructed!" << endl;
	}
	~BTest(){
		cout << "BTest Deconstruction succeeded!" << endl;
	}
	
public:
	shared_ptr<A> m_aptr;   //quote
};
//use
void test01()
{
	shared_ptr<ATest> pa(new ATest());
	shared_ptr<BTest> pb(new BTest());

	cout << pa.use_count() << endl;
	cout << pb.use_count() << endl;
}
int main()
{
	test01();
	system("pause");
	return 0;
}

1.2 the results are as follows:


It indicates that the destructors of ATest and BTest classes are called normally, indicating that the memory is released correctly.

2. Circular reference

2.1 codes are as follows:

#include<iostream>
#include<string>
#include<memory>
using namespace std;
class BTest;
class ATest
{
public:
	ATest(){
		cout << "ATest Successfully constructed!" << endl;
	}
	~ATest(){
		cout << "ATest Deconstruction succeeded!" << endl;
	}
public:
	shared_ptr<B> m_bptr;     //quote
};

class BTest
{
public:
	BTest(){
		cout << "BTest Successfully constructed!" << endl;
	}
	~BTest(){
		cout << "BTest Deconstruction succeeded!" << endl;
	}
	
public:
	shared_ptr<A> m_aptr;   //quote
};
//use
void test02()
{
	shared_ptr<ATest> pa(new ATest()); //use
	shared_ptr<BTest> pb(new BTest()); //use

	pa->m_bptr = pb;  
	pb->m_aptr = pa;
	cout << pa.use_count() << endl;
	cout << pb.use_count() << endl;
}
int main()
{
	test02();
	system("pause");
	return 0;
}

2.2 The results are as follows:


Indicates that the destructors of ATest and BTest classes are not called, indicating that the memory is not released correctly.

4, What problems can smart pointer circular references cause?

As shown in the results of 2.2 above, the circular reference of smart pointer will cause the resources from new to be unable to be released, resulting in memory leakage.

5, How to solve the problem of smart pointer circular reference?

1. Method

When defining objects, use strong intelligent pointers; Where an object is referenced, use a weak smart pointer

2. The code is as follows:

#include<iostream>
#include<string>
#include<memory>
using namespace std;
class BTest;
class ATest
{
public:
	ATest(){
		cout << "ATest Successfully constructed!" << endl;
	}
	~ATest(){
		cout << "ATest Deconstruction succeeded!" << endl;
	}
public:
    //Share_ PTR changed to weak_ptr
	weak_ptr<B> m_bptr;      //quote
};

class BTest
{
public:
	BTest(){
		cout << "BTest Successfully constructed!" << endl;
	}
	~BTest(){
		cout << "BTest Deconstruction succeeded!" << endl;
	}
	
public:
    //Share_ PTR changed to weak_ptr
	weak_ptr<A> m_aptr;      //quote
};
//use
void test03()
{
	shared_ptr<ATest> pa(new ATest()); //use
	shared_ptr<BTest> pb(new BTest()); //use

	pa->m_bptr = pb;  
	pb->m_aptr = pa;
	cout << pa.use_count() << endl;
	cout << pb.use_count() << endl;
}
int main()
{
	test02();
	system("pause");
	return 0;
}

3. Results


The result is consistent with the non cyclic reference, indicating that the resources are released correctly.

5, Member method call problem

1. Scene

2. The code is as follows:

#include<iostream>
#include<string>
#include<memory>
using namespace std;
/*
*/
class BTest;
class ATest
{
public:
	ATest(){
		cout << "ATest Successfully constructed!" << endl;
	}
	~ATest(){
		cout << "ATest Deconstruction succeeded!" << endl;
	}

	void funA()
	{
		cout << "ATest Object fun method!" << endl;
	}
public:
	weak_ptr<BTest> m_bptr;     //quote
};

class BTest
{
public:
	BTest(){
		cout << "BTest Successfully constructed!" << endl;
	}
	~BTest(){
		cout << "BTest Deconstruction succeeded!" << endl;
	}
	void funB()
	{
		shared_ptr<ATest> usptr = m_aptr.lock();  //Lifting method
		if (usptr!=nullptr)
		{
			usptr->funA();
		}
		//m_ aptr->funA();    //  Weak smart pointer cannot be called
	}
public:
	weak_ptr<ATest> m_aptr;   //quote
};
void test04()
{
	shared_ptr<ATest> pa(new ATest()); //use
	shared_ptr<BTest> pb(new BTest()); //use

	pa->m_bptr = pb;
	pb->m_aptr = pa;
	cout << pa.use_count() << endl;
	cout << pb.use_count() << endl;

	pb->funB();
}
int main()
{
	test04();
	system("pause");
	return 0;
}

3. Results


Successfully called.

summary

weak_ptr and shared_ptr.

To be improved.....

C + + smart pointer - use of shared_ptr

Topics: C++ Back-end