C++ smart pointers - create simple smart pointers (study notes 1)

This is the first post, please include a lot, if there is any mistake, please correct me

There are many related articles on the Internet. I just want to write a series of notes about the implementation of this smart pointer. I will start from scratch, and then verify the smart pointer I wrote step by step. I will not explain and record the principle. , because there are many on the Internet, so I will go directly through the code. This note is also the process of learning smart pointers. For beginners who want to learn smart pointers, you can refer to

1. Design and implementation of smart pointers: reference counting

Method to realize:

1. First create a smart pointer class to save the newly created data

#pragma once
#include <assert.h>
#include <memory>


//智能指针:引用计数
template<typename T>
class CSharedPtr
{
public:

	/*
	* 当创建全新的类时,进行保存,并创建计数
	*/
	CSharedPtr(T* ptr)
		:T_Ptr(ptr)
	{
		T_Count = new size_t(1);	
	}


	//拷贝构造的时候,引用+1,而不是创建新的
	CSharedPtr(const CSharedPtr& ptr)
	{
		if (this != &ptr)
		{
			T_Ptr = ptr.T_Ptr;
			T_Count = ptr.T_Count;
			++(*T_Count);
		}
	}

	//重载=
	CSharedPtr& operator=(const CSharedPtr& ptr)
	{
		if (T_Ptr == ptr.T_Ptr)
			return *this;
		(*ptr.T_Count)++;
		if (T_Ptr && (--(*T_Count) == 0 ))
		{
			delete T_Ptr;
			delete T_Count;
		}
		T_Ptr = ptr.T_Ptr;
		T_Count = ptr.T_Count;
		
		return *this;
	}

	~CSharedPtr()
	{
		if (--(*T_Count) == 0)
		{
			delete T_Ptr;
			delete T_Count;
		}
	}

	inline size_t GetCount(){ return *T_Count; }

private:
	T* T_Ptr;
	size_t* T_Count;
};

2. Create a test class and add print data in the destructor

#pragma once
#include <iostream>
#include <cstring>


class TestA
{
public:
	TestA(const std::string inName):_name(inName),_val(-1){}
	TestA(const std::string inName,int inVal):_name(inName),_val(inVal){}
	~TestA()
     { 
        std::cout<<"~TestA: create class name: " <<_name<< ": " <<_val << std::endl;
     }
private:

	std::string _name;
	int _val;
};

3. Then test in the main function

#include "CSharedPtr.h"
#include "TestA.h"
#include <iostream>

int main()
{
    //添加域,用以测试,类被析构和调用的情况
	{
		CSharedPtr<TestA> _A(new TestA("_A"));
		CSharedPtr<TestA> _B(_A);
		CSharedPtr<TestA> _C(new TestA("_C",10));

		_C=_B;

		std::cout << "A:"<< _A.GetCount() << std::endl;
		std::cout << "B:"<< _B.GetCount() << std::endl;
		std::cout << "C:"<< _C.GetCount() << std::endl;

	}
	
	return 0;
}

When running the program: the result is:

        

in:

        The first result: ~TestA: create class name: _C: 10 is  a call when   _C = _B  , this process will call the overloaded =  operation function of the smart pointer:  CSharedPtr& operator=(const CSharedPtr& ptr)

        Because _C has only one reference count (when it is created), when it is assigned a new value, the reference count is 0, that is, T_Count=0  . Therefore, the data originally created by _C will be deleted, and it will be called when it is deleted. The destructor of TestA, thus printing out  ~TestA: create class name: _C: 10

        The result of the 2nd, 3rd, and 4th lines is that the result of the reference count is 3, because the addresses of the three classes are all the same, which is the first created _A; 

        Why are the saved addresses all _A?

        Let's analyze this process:  

        First: CSharedPtr _A(new TestA("_A"));        // This is the first creation (at this point the reference count is 1)

                   CSharedPtr _B(_A);     //This is a copy structure in a smart pointer, it will assign the smart pointer data of _A to _B, and perform a reference count at the same time, check the function: CSharedPtr(const CSharedPtr& ptr )

        _A has a reference count of 2 so far

        The third reference count occurs in the process of _C = _B ; you can check the overloaded = function in the smart pointer class

        After executing _C=_B, the reference count of _A has reached 3 times, resulting in the printing results of lines 2, 3, and 4 being 3.

The last printed destructed data is because, when it comes to destructed, only _A is left

        So far, a simple smart pointer has been implemented

Guess you like

Origin blog.csdn.net/acdfg123/article/details/118226287