Pointer、SmartPointer、SharedPointer

Pointer

  智能指针的特点:
    智能指针可以像指针一样使用(重载->和*)
    智能指针生命周期结束自动释放内存空间
    智能指针只能指向堆空间中的内存
     禁止使用Delete释放智能指针指向的对象

  SmartPointer的特点:
    一片堆空间只可以属于一个智能指针对象
    拷贝构造或者赋值操作时,原指针置NULL(若新指针原不为NULL,释放指向的对象)新指针指向新对象
    可以用于多个指针指向同一个对象的场合

  SharedPointer的特点:
    一片堆空间可以被多个智能指针对象指向
    拷贝构造或者赋值操作时,计数+1,(若新指针原不为NULL,原对象的计数-1)新指针指向新对象
    如果计数减为0,才会释放指向的对象
    可以用于多个指针指向同一个对象的场合

  QPointer (Qt中)的特点:
    析构时 不会自动销毁所指向的对象
    当其指向的对象被销毁时,它会被自动 置NULL
    可用于QtGUI开发松耦合的场合

智能指针继承结构
    

  定义顶层抽象类,重载指针特征操作符
Pointer.h

#ifndef _Pointer_H_
#define _Pointer_H_

#include "include/CPlusPlus.h"
#include "include/Object.h"

namespace JYlib
{

template< typename T>
class Pointer:public Object//没有完成Object的虚函数—析构函数,所以是抽象类
{
protected:	//可以被继承
	T* m_pointer;

public:
	Pointer(T* p = NULL)
	{
		m_pointer = p;
	}

	T& operator *()
	{
		return (*m_pointer);
	}

	T* operator ->()
	{
		return m_pointer;
	}

	const T& operator *()const
	{
		return (*m_pointer);
	}

	const T* operator ->()const
	{
		return m_pointer;
	}

	T* get()const
	{
		return m_pointer;
	}

	bool IsNull()const
	{
		return (m_pointer == NULL);
	}
};


}


#endif

SmartPointer

SmartPointer.h

#ifndef _SmartPointer_H_
#define _SmartPointer_H_

#include "include/Pointer.h"

namespace JYlib
{

template< typename T>
class SmartPointer:public Pointer<T>//智能指针会自动释放堆空间,只能应用于指向堆空间的对象
{
protected:	//可以被继承

public:
    SmartPointer(T* p = NULL):Pointer<T>(p)
	{

	}

	SmartPointer(const SmartPointer<T> &obj)//原本的指针置空,同一内存只能一个指针指向
	{
		this->m_pointer = obj.m_pointer;

		const_cast<SmartPointer<T>&>(obj).m_pointer = NULL;
	}

	SmartPointer<T>& operator =(const SmartPointer<T> &obj)//原本的内存析构,指向新内存,并让原指针置空
	{
		if(this != &obj)
		{
			T* remove = this->m_pointer;//异常安全
			
			this->m_pointer = obj.m_pointer;

			const_cast<SmartPointer<T>&>(obj).m_pointer = NULL;

			delete remove;
		}
		
		return *this;
	}

	~SmartPointer()
	{
		delete this->m_pointer;
	}
};


}


#endif

SharedPointer

  利用计数机制,和重载比较操作符,来判断是否被多个智能指针指向
SharedPointer.h

#ifndef _SharedPointer_H_
#define _SharedPointer_H_
#include "Pointer.h"
#include "Exception.h"
#include <cstdlib>


namespace JYlib
{
/*
构造时创建一个内存空间,用指针指向它
拷贝构造时,创建的指针直接指向对方的内存空间
*/
template< typename T>
class SharedPointer:public Pointer<T>//智能指针会自动释放堆空间,只能应用于指向堆空间的对象
{
protected:	//可以被继承
	int* m_ref;//计数机制成员指针

	void assign(const SharedPointer<T> &obj)
	{
		this->m_pointer = obj.m_pointer;

		m_ref = obj.m_ref;

		if(m_ref)
		{
			(*m_ref)++;
		}
	}
public:
    SharedPointer(T* p = NULL):Pointer<T>(p),m_ref(NULL)
	{
		if(p)
		{
            m_ref = static_cast<int*>(malloc(sizeof(int)));

			if(this->m_ref)
			{
				*m_ref = 1;
				this->m_pointer = p;
			}
			else
			{
				THROW_EXCEPTION(NoEnoughMemoryException,"No memory to create SharedPointer object ...");
			}
		}
	}

	//清除原内容,指向新内容,内容有效,计数加1
    SharedPointer(const SharedPointer<T> &obj):Pointer<T>(obj.m_pointer)
	{
		assign(obj);
	}

	//清除原内容,指向新内容,内容有效,计数加1
	SharedPointer<T>& operator =(const SharedPointer<T> &obj)
	{
		if(this != &obj)
		{	
			clear();

			assign(obj);
		}
		
		return *this;
	}

	bool operator ==(const SharedPointer<T> &obj)
	{
		return (this->get() == obj.get());
	}

	bool operator !=(const SharedPointer<T> &obj)
	{
		return (this->get() != obj.get());
	}

	void clear()
	{
		if(this->m_pointer != NULL)
		{
			T* rem_pointer = this->m_pointer;//异常安全
			int* rem_ref = m_ref;

			this->m_pointer = NULL;
			m_ref = NULL;

			(*rem_ref)--;

			if((*rem_ref) == 0)
			{
				delete rem_pointer;
				delete rem_ref;
			}
		}
	}

	~SharedPointer()
	{
		clear();
	}
};


}


#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智能指针C++中用于管理动态分配的内存的一种机制。它们可以自动地在不再需要时释放内存,从而避免内存泄漏和悬挂指针的问题。 shared_ptr是一种引用计数智能指针,它可以跟踪有多少个shared_ptr指向同一个对象,并在没有引用时自动释放内存。当创建shared_ptr时,它会增加引用计数,当销毁或重置shared_ptr时,它会减少引用计数。只有当引用计数为0时,才会真正释放内存。\[1\]shared_ptr可以通过构造函数接受一个指向动态分配对象的指针来创建,也可以使用std::make_shared函数来创建。\[2\] unique_ptr是一种独占智能指针,它拥有对动态分配对象的唯一所有权。当unique_ptr被销毁时,它会自动释放内存。unique_ptr不能被复制,但可以通过std::move函数进行转移所有权。\[3\]unique_ptr可以通过构造函数接受一个指向动态分配对象的指针来创建。 weak_ptr是一种弱引用智能指针,它指向由shared_ptr管理的对象,但不会增加引用计数。weak_ptr可以用于解决shared_ptr的循环引用问题,因为它不会导致对象无法释放。\[1\]weak_ptr可以通过shared_ptr的构造函数来创建。 auto_ptr是C++11之前的一种智能指针,它类似于unique_ptr,但有一些限制和问题。auto_ptr在复制时会转移所有权,这可能导致悬挂指针的问题。因此,auto_ptr已经被unique_ptr取代,不推荐使用。 总结来说,shared_ptr是引用计数智能指针,unique_ptr是独占智能指针,weak_ptr是弱引用智能指针,而auto_ptr是已经过时的智能指针。它们各自有不同的用途和特点,可以根据具体的需求选择使用。 #### 引用[.reference_title] - *1* *2* *3* [C++11 解决内存泄露问题的智能指针shared_ptr、unique_ptr、weak_ptr](https://blog.csdn.net/weixin_44120785/article/details/128714630)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值