C++:智能指针( scope_ptr)

新智能指针的加入:

C++11之前,智能指针只有 auto_ptr 一种,但是后来发现它并不能很好的保证指针的安全可靠性,随之又出现了

shared_ptr     unique_ptr     weak_ptr   scope_ptr 这几种智能指针。

假如存在这样的代码
int main()
{
    SmartPtr sp1(new int);
    SmartPtr sp2(sp1);

    *sp1 = 20;
     return 0;
}

这里,SmartPtr即为之前博客实现的auto_ptr,显而易见,*sp1=20;这行会出现崩溃。

               C++:智能指针( scope_ptr)_第1张图片

解决方案:

 之前的auto_ptr,管理权唯一,释放权也唯一,现在要使智能指针管理权不唯一,释放权唯一。

带有标志位(flag)的智能指针

如图:

                 C++:智能指针( scope_ptr)_第2张图片

             C++:智能指针( scope_ptr)_第3张图片

代码:

#include

using namespace std;

template
class SmartPtr
{
public:
	SmartPtr(T* ptr) :mptr(ptr)
	{
		flag = true;
	}
	SmartPtr(const SmartPtr& rhs):mptr(rhs.mptr)
	{
		flag = rhs.flag;
		rhs.flag = false;
	}
	SmartPtr& operator=(const SmartPtr& rhs)
	{
		if (this != &rhs)
		{
			~SmartPtr();
			mptr = rhs.mptr;
			flag = rhs.flag;
			rhs.flag = false;
		}
		return *this;
	}
	~SmartPtr()
	{
		if (flag)
		{
			delete mptr;
		}
		mptr = NULL;
	}
	T& operator*()
	{
		return *mptr;
	}
	T* operator->()
	{
		return mptr;
	}
private:
	T* mptr;
	mutable bool flag;//去除常性
};

int main()
{
	SmartPtr sp1(new int);
	SmartPtr sp2(sp1);
        SmartPtr sp3(sp1);

	*sp1 = 20;

	return 0;
}

这里程序不会崩溃,有释放权的只有sp2。

又一个问题

因为释放权的转移,有可能导致堆内存被提前释放

void func(SmartPtr sp)//实参传形参 调用拷贝构造
{

}

int main()
{
	SmartPtr sp1(new int);
	SmartPtr sp2(sp1);
	SmartPtr sp3(sp1);

	func(sp2);//;执行结束后,形参对象销毁  相当于堆内存已经归还给系统
	*sp1 = 20;//使用不可使用的内存块 野指针 该内存块可能被再分配
	return 0;
}

调用这个函数,实参传形参 调用拷贝构造,func(sp2);//;执行结束后,形参对象销毁  相当于堆内存已经归还给系统。

*sp1 = 20;//使用不可使用的内存块 野指针 该内存块可能被再分配,会出现不可预期的数据错误。

解决: ScopePtr  不允许多个智能指针对象指向同一块堆内存

#include

using namespace std;

template
class ScopePtr//不允许多个智能指针对象指向同一块堆内存
{
public:
	ScopePtr(T* ptr=NULL):mptr(ptr)
	{
		//mptr = ptr;
	}
	~ScopePtr()
    {
		delete mptr;
		mptr = NULL;
	}
	T& operator*()
	{
		return *mptr;
	}
	T* operator->()
	{
		return mptr;
	}
private:
	ScopePtr(const ScopePtr& rhs);//不需要调用,因为不允许多个智能指针对象指向同一块堆内存
	ScopePtr& operator=(const ScopePtr& rhs);//不允许多个智能指针对象指向同一块堆内存
private:
	T* mptr;
};

int main()
{
	int* p = new int;
	ScopePtr sp1(p);
	ScopePtr sp2(p);
	ScopePtr sp3(p);//后构造的先析构
	return 0;
}

    int* p = new int;
    ScopePtr sp1(p);
    ScopePtr sp2(p);
    ScopePtr sp3(p);//后构造的先析构
    

这个程序会崩溃,后构造的先析构,然后先构造的再析构时,delete野指针,程序崩溃。

你可能感兴趣的:(c++)