C++:智能指针(auto_ptr)

智能指针:
       在C++中使用堆内存是非常频繁的操作,堆内存的申请和释放都由程序员自己管理。使用普通指针,容易造成堆内存泄露,二次释放等问题,使用智能指针能更好的管理堆内存。C++11中引入了智能指针的概念,方便管理堆内存。

栈、堆区别

栈:系统开辟 系统释放

堆:手动开辟 手动释放

设计:手动开辟 系统释放

图示:

                        

手动开辟堆内存,利用对象生存周期结束后会调用析构,让对象来管理这个堆内存,从而达到 手动开辟,系统析构的目的。

最初始的智能指针:管理权唯一
如果有多个智能指针指向同一个堆内存,会在拷贝构造或赋值过程中让其他的智能指针失效(置空)

#include<iostream>

using namespace std;

template<typename T>
class SmartPtr
{
public:
	SmartPtr(T* ptr=NULL):mptr(ptr){}
	SmartPtr(const SmartPtr& rhs):mptr(rhs.mptr)//让两个智能指针指向同一个堆内存
	{
		rhs.Release();
	}
	SmartPtr<T> operator=(const SmartPtr<T>& rhs)
	{
		if (this != &rhs)
		{
			delete mptr;//要么有唯一智能指针指向堆内存,要么指向空 
			mptr = rhs.mptr;
			rhs.Release();
		}
		return *this;
        }
	~SmartPtr()
	{
		delete mptr;
		mptr = NULL;
	}
private:
	void Release()const//旧的智能指针置为空
	{
		(T*)mptr = NULL;
	}
private:
	T* mptr;
};

int main()
{
	int *p=new int;//堆内存
	SmartPtr<int> sp1(p);
	SmartPtr<int> sp2(sp1);
        sp1=sp2;
	return 0;
}

调试结果:

        

可以看出,当生成sp2时,sp1指向为空,指向的内存正是p所指向的堆内存。
        

可以看出,sp1=sp2;执行后,内存的管理权在sp1手上。

普通指针有指向和解引用的使用方法,同理智能指针也具有,需要运算符的重载。

#include<iostream>

using namespace std;

template<typename T>
class SmartPtr
{
public:
	SmartPtr(T* ptr = NULL) :mptr(ptr) {}
	SmartPtr(const SmartPtr& rhs) :mptr(rhs.mptr)//让两个智能指针指向同一个堆内存
	{
		rhs.Release();
	}
	SmartPtr<T>& operator=(const SmartPtr<T>& rhs)
	{
		if (this != &rhs)
		{
			delete mptr;//要么有唯一智能指针指向堆内存,要么指向空 
			mptr = rhs.mptr;
			rhs.Release();
		}
		return *this;
    }
	T& operator*()//解引用运算符的重载
	{
		return *mptr;
	}
	T* operator->()//指向运算符的重载
	{
		return mptr;
	}
	~SmartPtr()
	{
		delete mptr;
		mptr = NULL;
	}
private:
	void Release()const//旧的智能指针置为空
	{
		(T*)mptr = NULL;
	}
private:
	T* mptr;
};

class Test
{
public:
	Test(int a):ma(a){}
	void Show()
	{
		cout << ma << endl;
	}
private:
	int ma;
};

int main()
{
	int *p=new int;//堆内存
	SmartPtr<int> sp1(p);
	SmartPtr<int> sp2(sp1);
	sp1 = sp2;
        //普通指针的用法
	Test *ptest = new Test(30);//成员变量是 Test *mptr;
	ptest->Show();
	//智能指针的用法
	SmartPtr<Test> sp3(ptest);
	sp3->Show();
	(*sp3.operator->()).Show();
	return 0;
}

解释:(*sp3.operator->()).Show();//(sp3.operator->())->Show();

sp3.operator->()返回一个 T* 指针,*T解引用,即对象,对象调用方法,合情合理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章