• C++智能指针[下](shared_ptr/weak_ptr/循环引用/删除器)


    4.智能指针[shared_ptr]

    4.1设计理念

    成员属性

    在这里插入图片描述
    在这里插入图片描述

    每一个对象除了有一个主指针外 还有一个副指针用来计数 为什么不设置成int而设置成int*?

    同一块空间被两个指针指向 当编译器得到需要销毁指针的指令时 会先判断这是不是最后一个指针 即count==1 时才释放空间 其余情况均只是的计数-- 而不释放空间 这是我们的最初目的 如果设置成int意味着每一个对象有各自的count 当ptr1拷贝给ptr2 我们想要的是 有一块空间单独来计数 如果执行拷贝则计数++ 即我们需要一块共有的空间来实现

    不是要实现共有吗 为什么不直接用静态变量?

    静态变量可以实现共有没错 但他是当前类的所有对象共有 举例说明: 代码的本意是ptr1 ptr2 ptr3指向同一块空间 此时count == 3 ptr4指向另一块空间时 代码的本意是count = 1 但是同时改变了ptr1/2/3

    4.2主要接口

    拷贝构造

    在这里插入图片描述

    	//赋值重载
    	//1."自己"给"自己"赋值
    	//不仅仅是p1 = p1 还要考虑p2 = p1 但之前p2就 = p1
    	//2.左 = 右 赋值后 
    	// 左指针指向空间的指针少了一个 左指针的count-- 进一步考虑count--后==0的情况
    	// 右指针指向空间的指针多了一个 右指针的count++
    	shared_ptr<T>& operator=(const shared_ptr<T>& sp)
    	{
    		//"自己"给"自己"赋值: "自己"的本质
    		if (_ptr != sp._ptr)
    		{
    			//count--
    			Release();
    
    			_ptr = sp._ptr;
    			_pcount = sp._pcount;
    			_pmtx = sp._pmtx;
    
    			//count++
    			AddCount();
    		}
    
    		return *this;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    4.3引用计数线程安全问题

    测试线程安全

    通过对计数引用的加锁保护使得类线程安全
    	struct Date
    	{
    		int _year = 0;
    		int _month = 0;
    		int _day = 0;
    	};
    	void SharePtrFunc(ape::shared_ptr<Date>& sp, size_t n, mutex& mtx)
    	{
    		cout << "   SharePtrFunc: sp.GetPtr() == " << sp.GetPtr() << endl;
    
    		for (size_t i = 0; i < n; ++i)
    		{
    			ape::shared_ptr<Date> copy(sp);
    		}
    	}
    
    	void test_shared_safe()
    	{
    		ape::shared_ptr<Date> p(new Date);
    		cout << "test_shared_safe: p.GetPtr() == " << p.GetPtr() << endl;
    
    		const size_t n = 10000;
    		mutex mtx;
    
    		//线程引用传参即便mtx已经是引用 此处仍然需要使用库函数ref();
    		thread t1(SharePtrFunc, ref(p), n, ref(mtx));
    		thread t2(SharePtrFunc, ref(p), n, ref(mtx));
    
    		t1.join();
    		t2.join();
    
    		cout << "p.GetCount(): == " << p.GetCount() << endl;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    在这里插入图片描述

    类实例化的对象使用时需要手动加锁保护

    在这里插入图片描述
    在这里插入图片描述

    "锁"的引进

    在这里插入图片描述

    线程引用传参问题

    在这里插入图片描述

    简单理解为 p在传给sp前是需要先调用线程的构造函数的 期间发生了某种动作 使得失去引用属性

    4.4整体代码

    template<class T>
    class shared_ptr
    {
    public:
    	//构造函数
    	shared_ptr(T* ptr)
    		:_ptr(ptr)
    		, _pcount(new int(1))
    		, _pmtx(new mutex)
    	{
    
    	}
    
    	void Release()
    	{
    		//上锁
    		_pmtx->lock();
    		//不可释放锁
    		bool deleteFlag = false;
    
    		if (--(*_pcount) == 0)
    		{
    			cout << "delete:" << _ptr << endl;
    			delete _ptr;
    			delete _pcount;
    			//可释放锁
    			deleteFlag = true;
    		}
    		//解锁
    		_pmtx->unlock();
    		//判断并释放锁
    		if (deleteFlag)
    		{
    			delete _pmtx;
    		}
    	}
    	//void Release()
    	//{
    	//	_pmtx->lock();
    	//	bool deleteFlag = false;
    	//	if (--(*_pcount) == 0)
    	//	{
    	//		if (_ptr)
    	//		{
    	//			//cout << "delete:" << _ptr << endl;
    	//			//delete _ptr;
    	//
    	//			// 删除器进行删除
    	//			_del(_ptr);
    	//		}
    	//
    	//		delete _pcount;
    	//		deleteFlag = true;
    	//	}
    	//
    	//	_pmtx->unlock();
    	//
    	//	if (deleteFlag)
    	//	{
    	//		delete _pmtx;
    	//	}
    	//}
    	void AddCount()
    	{
    		_pmtx->lock();
    
    		++(*_pcount);
    
    		_pmtx->unlock();
    	}
    
    	//拷贝构造
    	shared_ptr(const shared_ptr<T>& sp)
    		:_ptr(sp._ptr)
    		, _pcount(sp._pcount)
    		, _pmtx(sp._pmtx)
    	{
    		AddCount();
    	}
    
    	//赋值重载
    	//1."自己"给"自己"赋值
    	//不仅仅是p1 = p1 还要考虑p2 = p1 但之前p2就 = p1
    	//2.左 = 右 赋值后 
    	// 左指针指向空间的指针少了一个 左指针的count-- 进一步考虑count--后==0的情况
    	// 右指针指向空间的指针多了一个 右指针的count++
    	shared_ptr<T>& operator=(const shared_ptr<T>& sp)
    	{
    		//"自己"给"自己"赋值: "自己"的本质
    		if (_ptr != sp._ptr)
    		{
    			//count--
    			Release();
    
    			_ptr = sp._ptr;
    			_pcount = sp._pcount;
    			_pmtx = sp._pmtx;
    
    			//count++
    			AddCount();
    		}
    
    		return *this;
    	}
    
    	//析构函数
    	~shared_ptr()
    	{
    		Release();
    	}
    
    	T& operator*()
    	{
    		return *_ptr;
    	}
    
    	T* operator->()
    	{
    		return _ptr;
    	}
    
    	T* GetPtr()
    	{
    		return _ptr;
    	}
    
    	int GetCount()
    	{
    		return *_pcount;
    	}
    
    private:
    	T* _ptr;
    	int* _pcount;
    	mutex* _pmtx;
    };
    
    void test_shared()
    {
    	shared_ptr<int> sp1(new int(1));
    	shared_ptr<int> sp2(sp1);
    	shared_ptr<int> sp3(sp2);
    
    	shared_ptr<int> sp4(new int(10));
    
    	sp1 = sp4;
    	sp4 = sp1;
    
    	sp1 = sp1;
    	sp1 = sp2;
    }
    
    
    //   线程安全问题   ///
    struct Date
    {
    	int _year = 0;
    	int _month = 0;
    	int _day = 0;
    };
    
    void SharePtrFunc(ape::shared_ptr<Date>& sp, size_t n, mutex& mtx)
    {
    	cout << "   SharePtrFunc: sp.GetPtr() == " << sp.GetPtr() << endl;
    
    	cout << "   SharePtrFunc: &sp == " << &sp << endl;
    
    	for (size_t i = 0; i < n; ++i)
    	{
    		ape::shared_ptr<Date> copy(sp);
    
    		mtx.lock();
    
    		sp->_year++;
    		sp->_day++;
    		sp->_month++;
    
    	    mtx.unlock();
    	}
    }
    
    void test_shared_safe()
    {
    	ape::shared_ptr<Date> p(new Date);
    	cout << "test_shared_safe: p.GetPtr() == " << p.GetPtr() << endl;
    
    	cout << "test_shared_safe: &p == " << &p << endl;
    
    	const size_t n = 100000;
    	mutex mtx;
    
    	//线程引用传参即便p和mtx已经是引用 此处仍然需要使用库函数ref();
    	thread t1(SharePtrFunc, ref(p), n, ref(mtx));
    	thread t2(SharePtrFunc, ref(p), n, ref(mtx));
    
    	t1.join();
    	t2.join();
    
    	cout << "p.GetCount(): == " << p.GetCount() << endl;
    
    	cout << "p->_year  == " << p->_year << endl;
    	cout << "p->_month == " << p->_month << endl;
    	cout << "p->_month == " << p->_month << endl;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205

    5.循环引用问题

    5.1问题的引入

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    5.2分析造成此问题的原因

    在这里插入图片描述

    为了解决此问题 需要引进weaked_ptr 我们需要了解的是
    智能指针shared_ptr满足

    1. 符合RAII思想
    2. 可以像指针一样使用
    3. 支持拷贝

    智能指针weaked_ptr满足

    1. 不符合RAII思想
    2. 可以像指针一样使用
    3. 辅助解决shared_ptr的循环引用问题
    4. weaked_ptr可以指向资源,但是不参与管理,不增加引用计数

    实际上库里的智能指针远比我们上述讲到的复杂得多 为了便于学习和理解 我们只学习核心框架 需要了解的是 库里所支持的这两个函数在这里插入图片描述
    weaked_ptr有自己的count 配合expired来判断所指向资源是否还有被指向的必要 即weaked_ptr可以指向资源,但是不参与管理,不增加shared_ptr引用计数 所以存在于一种所指向资源的计数已经成0 此时expired判断是否失效 若所指向资源失效weaked_ptr就不再指向

    在这里插入图片描述

    5.3weak_ptr的主要代码

    template<class T>
    class weak_ptr
    {
    public:
    	weak_ptr()
    		:_ptr(nullptr)
    	{
    	
    	}
    
    	weak_ptr(const shared_ptr<T>& sp)
    		:_ptr(sp.GetPtr())
    	{
    	
    	}
    
    	T& operator*()
    	{
    		return *_ptr;
    	}
    
    	T* operator->()
    	{
    		return _ptr;
    	}
    
    	T* GetPtr()
    	{
    		return _ptr;
    	}
    
    private:
    	T* _ptr;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    6.数组对象的删除问题

    6.1代码问题

    在这里插入图片描述

    6.2std::shared_ptr面对此问题的解决方案

    1.首先看std::shared_ptr::~shared_ptr

    在这里插入图片描述

    即库里的shared_ptr::~shared_ptr与我们写的析构函数不同之处在于 一个对象在实例化时 他会判断是否接受了参数deleter 如果接收则析构时调用deleter析构 若没有接收deleter则正常析构

    2.删除器的传参及使用

    在这里插入图片描述

    销毁对象。但是,以前,根据成员use_count的值,它可能会产生以下副作用:如果use_count大于1(即该对象与其他shared_ptr对象共享其托管对象的所有权):与其共享所有权的其他对象的使用计数将减少1。如果use_coount为1(即,该对象是托管指针的唯一所有者):它所拥有的指针被删除(如果shared_ptr对象是用特殊的deleter构造的,则调用它;否则,函数使用运算符delete)。如果use_count为零(即对象为空),则此析构函数没有副作用。

    	template<class T>
    	struct DeleteArray
    	{
    		void operator()(T* ptr)
    		{
    			cout << "匿名对象DeleteArray(): " << ptr << endl;
    			delete[] ptr;
    		}
    	};
    	void test_std_shared_deletor()
    	{
    		//template  
    		//shared_ptr (U* p, D del);   带删除器的构造函数
    
    		std::shared_ptr<Date> sparr1(new Date[10], DeleteArray<Date>());
    
    		std::shared_ptr<Date> sparr2(new Date[10],
    			[](Date* ptr)
    			{
    				cout << "lambda表达式 delete[]: " << ptr << endl;
    				delete[] ptr;
    			}
    		);
    
    		auto deleter = [](Date* ptr)
    			{
    				cout << "lambda表达式 delete[]: " << ptr << endl;
    				delete[] ptr;
    			};
    		std::shared_ptr<Date> sparr3(new Date[10], deleter);
    
    		std::shared_ptr<FILE> spFile(fopen("Test.cpp", "r"),
    			[](FILE* ptr)
    			{
    				cout << "lambda表达式 delete[]: " << ptr << endl;
    				fclose(ptr);
    			}
    		);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    在这里插入图片描述

    3.添加封装删除器

    在这里插入图片描述

    在这里插入图片描述

    7.总结

    7.1完整代码

    #pragma once
    
    #include 
    #include 
    #include 
    
    namespace ape
    {
    	template<class T>
    	class shared_ptr
    	{
    	public:
    		//构造函数
    		shared_ptr(T* ptr = nullptr)
    			:_ptr(ptr)
    			, _pcount(new int(1))
    			, _pmtx(new mutex)
    		{
    
    		}
    
    		//删除器构造函数
    		template<class D>
    		shared_ptr(T* ptr, D del)
    			:_ptr(ptr)
    			, _pcount(new int(1))
    			, _pmtx(new mutex)
    			, _del(del)
    		{
    		
    		}
    
    		//非删除器Release()
    		/*
    		void Release()
    		{
    			//上锁
    			_pmtx->lock();
    			//不可释放锁
    			bool deleteFlag = false;
    
    			if (--(*_pcount) == 0)
    			{
    				if (_ptr != nullptr)
    				{
    					cout << "delete:" << _ptr << endl;
    					delete _ptr;
    				}
    				
    				delete _pcount;
    				//可释放锁
    				deleteFlag = true;
    			}
    			//解锁
    			_pmtx->unlock();
    			//判断并释放锁
    			if (deleteFlag)
    			{
    				delete _pmtx;
    			}
    		}
    		*/
    		
    		//删除器Release()
    		void Release()
    		{
    			_pmtx->lock();
    			bool deleteFlag = false;
    
    			if (--(*_pcount) == 0)
    			{
    				if (_ptr != nullptr)
    				{
    					_del(_ptr);
    				}
    		
    				delete _pcount;
    				deleteFlag = true;
    			}
    		
    			_pmtx->unlock();
    		
    			if (deleteFlag)
    			{
    				delete _pmtx;
    			}
    		}
    		void AddCount()
    		{
    			_pmtx->lock();
    
    			++(*_pcount);
    
    			_pmtx->unlock();
    		}
    
    		//拷贝构造
    		shared_ptr(const shared_ptr<T>& sp)
    			:_ptr(sp._ptr)
    			, _pcount(sp._pcount)
    			, _pmtx(sp._pmtx)
    		{
    			AddCount();
    		}
    
    		//赋值重载
    		//1."自己"给"自己"赋值
    		//不仅仅是p1 = p1 还要考虑p2 = p1 但之前p2就 = p1
    		//2.左 = 右 赋值后 
    		// 左指针指向空间的指针少了一个 左指针的count-- 进一步考虑count--后==0的情况
    		// 右指针指向空间的指针多了一个 右指针的count++
    		shared_ptr<T>& operator=(const shared_ptr<T>& sp)
    		{
    			//"自己"给"自己"赋值: "自己"的本质
    			if (_ptr != sp._ptr)
    			{
    				//count--
    				Release();
    
    				_ptr = sp._ptr;
    				_pcount = sp._pcount;
    				_pmtx = sp._pmtx;
    
    				//count++
    				AddCount();
    			}
    
    			return *this;
    		}
    
    		//析构函数
    		~shared_ptr()
    		{
    			Release();
    		}
    
    		T& operator*()
    		{
    			return *_ptr;
    		}
    
    		T* operator->()
    		{
    			return _ptr;
    		}
    
    		T* GetPtr() const
    		{
    			return _ptr;
    		}
    
    		int GetCount() const
    		{
    			return *_pcount;
    		}
    
    	private:
    		T* _ptr;
    		int* _pcount;
    		mutex* _pmtx;
    
    		//包装器
    		//缺省值处理情况: ape::shared_ptr sp(new Date);
    		//因为你析构时默认使用删除器 那么遇到没有显示传的要使用缺省值
    
    		//构造函数传deleter时 可以是仿函数 lambda表达式 函数指针 此处用包装器接收
    		function<void(T*)> _del = [](T* ptr)
    			{
    				cout << "lambda表达式 delete: " << ptr << endl;
    				delete ptr;
    			};
    	};
    
    	void test_shared()
    	{
    		shared_ptr<int> sp1(new int(1));
    		shared_ptr<int> sp2(sp1);
    		shared_ptr<int> sp3(sp2);
    
    		shared_ptr<int> sp4(new int(10));
    
    		sp1 = sp4;
    		sp4 = sp1;
    
    		sp1 = sp1;
    		sp1 = sp2;
    	}
    
    
    	//   线程安全问题   ///
    	struct Date
    	{
    		int _year = 0;
    		int _month = 0;
    		int _day = 0;
    
    		~Date()
    		{
    
    		}
    	};
    
    	void SharePtrFunc(ape::shared_ptr<Date>& sp, size_t n, mutex& mtx)
    	{
    		cout << "   SharePtrFunc: sp.GetPtr() == " << sp.GetPtr() << endl;
    
    		cout << "   SharePtrFunc: &sp == " << &sp << endl;
    
    		for (size_t i = 0; i < n; ++i)
    		{
    			ape::shared_ptr<Date> copy(sp);
    
    			mtx.lock();
    
    			sp->_year++;
    			sp->_day++;
    			sp->_month++;
    
    		    mtx.unlock();
    		}
    	}
    
    	void test_shared_safe()
    	{
    		ape::shared_ptr<Date> p(new Date);
    		cout << "test_shared_safe: p.GetPtr() == " << p.GetPtr() << endl;
    
    		cout << "test_shared_safe: &p == " << &p << endl;
    
    		const size_t n = 100000;
    		mutex mtx;
    
    		//线程引用传参即便p和mtx已经是引用 此处仍然需要使用库函数ref();
    		thread t1(SharePtrFunc, ref(p), n, ref(mtx));
    		thread t2(SharePtrFunc, ref(p), n, ref(mtx));
    
    		t1.join();
    		t2.join();
    
    		cout << "p.GetCount(): == " << p.GetCount() << endl;
    
    		cout << "p->_year  == " << p->_year << endl;
    		cout << "p->_month == " << p->_month << endl;
    		cout << "p->_month == " << p->_month << endl;
    
    	}
    
    	template<class T>
    	class weak_ptr
    	{
    	public:
    		weak_ptr()
    			:_ptr(nullptr)
    		{
    		
    		}
    
    		weak_ptr(const shared_ptr<T>& sp)
    			:_ptr(sp.GetPtr())
    		{
    		
    		}
    
    		T& operator*()
    		{
    			return *_ptr;
    		}
    
    		T* operator->()
    		{
    			return _ptr;
    		}
    
    		T* GetPtr()
    		{
    			return _ptr;
    		}
    
    	private:
    		T* _ptr;
    	};
    
    	// 循环引用
    	struct ListNode
    	{
    
    		/*普通写法
    		ListNode* _next;
    		ListNode* _prev;
    		int _val;
    		*/
    
    		
    		/*shared_ptr
    		ape::shared_ptr _next;
    		ape::shared_ptr _prev;
    		int _val;
    		*/
    
    		//weaked_ptr
    		ape::weak_ptr<ListNode> _next;
    		ape::weak_ptr<ListNode> _prev;
    		int _val;
    
    		~ListNode()
    		{
    			cout << "~ListNode()" << endl;
    		}
    	};
    
    	// 循环引用
    	void test_shared_cycle()
    	{
    		/*
    		常规写法 -- 抛异常场景不适合
    		ListNode* n1 = new ListNode;
    		ListNode* n2 = new ListNode;
    
    		n1->_next = n2;
    		n2->_prev = n1;
    
    		delete n1;
    		delete n2;
    		*/
    
    		//智能指针写法
    		ape::shared_ptr<ListNode> n1(new ListNode);
    		ape::shared_ptr<ListNode> n2(new ListNode);
    
    		//内置类型 = 自定义类型 -- error
    		/*
    		ListNode* _next;
    		ListNode* _prev;
    		int _val;
    
    		ape::shared_ptr n1(new ListNode);
    		ape::shared_ptr n2(new ListNode);
    
    		n1->_next = n2;
    		n2->_prev = n1;
    		*/
    
    		/*shared_ptr: 引发循环引用问题
    		ape::shared_ptr _next;
    		ape::shared_ptr _prev;
    		int _val;
    
    		ape::shared_ptr n1(new ListNode);
    		ape::shared_ptr n2(new ListNode);
    
    		n1->_next = n2;
    		n2->_prev = n1;
    		*/
    		
    		/*weak_ptr: 解决循环引用
    		ape::weak_ptr _next;
    		ape::weak_ptr _prev;
    		int _val;
    
    		ape::shared_ptr n1(new ListNode);
    		ape::shared_ptr n2(new ListNode);
            */
    		cout << "n1.GetCount() == " << n1.GetCount() << endl;
    		cout << "n2.GetCount() == " << n2.GetCount() << endl;
    		n1->_next = n2;
    		n2->_prev = n1;
    		cout << "n1.GetCount() == " << n1.GetCount() << endl;
    		cout << "n2.GetCount() == " << n2.GetCount() << endl;
    
    	}
    
    /
    	 //定制删除器 -- 可调用对象
    	
    	template<class T>
    	struct DeleteArray
    	{
    		void operator()(T* ptr)
    		{
    			cout << "匿名对象DeleteArray(): " << ptr << endl;
    			delete[] ptr;
    		}
    	};
    
    	//std库deleter的学习
    	/*
    	void test_std_shared_deletor()
    	{
    		//template  
    		//shared_ptr (U* p, D del);   带删除器的构造函数
    
    		std::shared_ptr sparr1(new Date[10], DeleteArray());
    
    		std::shared_ptr sparr2(new Date[10],
    			[](Date* ptr)
    			{
    				cout << "lambda表达式 delete[]: " << ptr << endl;
    				delete[] ptr;
    			}
    		);
    
    		auto deleter = [](Date* ptr)
    			{
    				cout << "lambda表达式 delete[]: " << ptr << endl;
    				delete[] ptr;
    			};
    		std::shared_ptr sparr3(new Date[10], deleter);
    
    		std::shared_ptr spFile(fopen("Test.cpp", "r"),
    			[](FILE* ptr)
    			{
    				cout << "lambda表达式 delete[]: " << ptr << endl;
    				fclose(ptr);
    			}
    		);
    	}
    	*/
    
    	//删除器构造函数
    	/*
    	template
    	shared_ptr(T* ptr, D del)
    		:_ptr(ptr)
    		, _pcount(new int(1))
    		, _pmtx(new mutex)
    		, _del(del)
    	{
    
    	}
    	*/
    	void test_ape_shared_deleter()
    	{ 
    		ape::shared_ptr<Date> sp(new Date);
    
    		ape::shared_ptr<Date> sparr1(new Date[10], DeleteArray<Date>());
    		ape::shared_ptr<Date> sparr2(new Date[10], 
    			[](Date* ptr) 
    			{
    			cout << "lambda表达式 delete[]: " << ptr << endl;
    			delete[] ptr;
    			}
    		);
    
    		auto deleter = [](Date* ptr)
    			{
    				cout << "lambda表达式 delete[]: " << ptr << endl;
    				delete[] ptr;
    			};
    		ape::shared_ptr<Date> sparr3(new Date[10], deleter);
    
    		ape::shared_ptr<FILE> spFile(fopen("Test.cpp", "r"),
    			[](FILE* ptr)
    			{
    			cout << "lambda表达式 delete[]: " << ptr << endl;
    			fclose(ptr);
    			}
    		);
    	}
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404
    • 405
    • 406
    • 407
    • 408
    • 409
    • 410
    • 411
    • 412
    • 413
    • 414
    • 415
    • 416
    • 417
    • 418
    • 419
    • 420
    • 421
    • 422
    • 423
    • 424
    • 425
    • 426
    • 427
    • 428
    • 429
    • 430
    • 431
    • 432
    • 433
    • 434
    • 435
    • 436
    • 437
    • 438
    • 439
    • 440
    • 441
    • 442
    • 443
    • 444
    • 445
    • 446
    • 447
    • 448
    • 449
    • 450
    • 451
    • 452
    • 453
    • 454
    • 455
    • 456
    • 457
    • 458
    • 459
    • 460
    • 461

    7.2C++11和Boost智能指针的关系

    1. C++ 98 中产生了第一个智能指针auto_ptr.
    2. C++ boost给出了更实用的scoped_ptr/shared_ptr/weak_ptr.
    3. C++ TR1,引入shared_ptr。[TR1不是标准版]
    4. C++ 11引入了unique_ptr/shared_ptr/weak_ptr。unique_ptr对应boost的scoped_ptr。[实现原理参考boost实现]
  • 相关阅读:
    为hade增加model自动生成功能
    QGIS制作精美地图
    微信小程序毕业设计论文_SSM项目会议预约管理+后台管理系统_项目源代码
    基于粒子群优化的BP神经网络算法
    【call,apply,bind】手写call,apply,bind的方法
    使用链表实现栈操作
    基于ssm+Javaweb的OA小型企业资源管理系统-计算机毕业设计
    这些客厅背景墙,你都收藏了吗?福州中宅装饰,福州装修
    婴儿摇椅出口亚马逊欧盟CE认证检测标准
    LIO-SAM 详读代码笔记 -- 5.MapOptimization
  • 原文地址:https://blog.csdn.net/LHRan_ran_/article/details/134017212