vc版auto_ptr智能指针实现

1 vc版auto_ptr智能指针实现

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
//#include<memory>
#include <vld.h>
using namespace std;

template<class _Ty>
class AutoPtr
{
public:
	// 默认构造函数,_Ptr为空时,没有任何空间的管理权
	AutoPtr(_Ty *p = 0) :_Owns(p != 0), _Ptr(p){}

	// 拷贝构造函数,调用_Y.Release()保证在_Ptr成员赋值时拥有权转移出去
	AutoPtr(const AutoPtr<_Ty> &_Y):_Owns(_Y._Owns),_Ptr(_Y.Release()){}

	// 赋值语句
	AutoPtr<_Ty>& operator=(const AutoPtr<_Ty> &_Y)
	{
		if (this != &_Y)
		{
			/* 两个智能指针的空间管理对象不同,形如
			 * auto_ptr<int> q1(a),q2(b);
			 * q1 = q2
			 */
			if (_Ptr != _Y._Ptr)
			{
				// 若拥有空间管理权,释放原来的空间
				if(_Owns)
					delete _Ptr;
				_Owns = _Y._Owns;
			}
			/* 两个智能指针的空间管理对象相同,形如
			 * int a = new int
			 * auto_ptr<int> q1(a),q2(a);
			 * q1 = q2,空间管理对象相同时_Ptr空间不释放
			 * 只要保证拥有权正确转移即可
			 * 这里还有对_Y._Owns做判断,是要保证拥有权不会丢失
			 * 防止q1的拥有权为真,q2的拥有权为假从而直接赋值后
			 * 拥有权丢失的情况
			 */
			else if (_Y._Owns)
			{
				_Owns = true;
			}
			_Ptr = _Y.Release();
		}
		return *this;
	}
	// 重载* 使对象有指针取*的特性
	_Ty& operator*()const
	{
		return *_Ptr;
	}
	// 重载-> 使对象有指针 -> 运算的特性
	_Ty* operator->()const
	{
		return _Ptr;
	}
	// 在_Ptr成员赋值时保证拥有权转移出去
	_Ty* Release()const
	{
		// 强转,去掉this指针的常性以改变成员_Owns的值
		((AutoPtr<_Ty>*)(this))->_Owns = false;
		return _Ptr;
	}
	~AutoPtr()
	{
		// 拥有权为真在析构智能指针时才能释放空间
		if (_Owns)
			delete _Ptr;
	}
private:
	/* 拥有权,拥有权为真才有资格释放智能指针管理的空间
	 * 为了防止在拷贝构造或赋值时,同一块空间被多个智能指针对象管理
	 * 造成同一块空间被多重释放,因此要保证智能指针在拷贝或赋值时拥有权
	 * 的正确转移,即任何时刻只能有一个智能指针对一块空间有拥有权
	 */
	bool _Owns;
	_Ty* _Ptr;
};

class Test
{
public:
	void fun()
	{
		cout << "Test fun" << endl;
	}
};
int main() 
{
	int *p = new int(10);
	AutoPtr<int> q(p);
	AutoPtr<int> q2(q); // 拷贝构造转移空间管理权
	q2 = q; // 赋值转移空间管理权
	cout << *q2 << endl;

	*q = 1000;
	cout << *q << " " << *q2 << endl;

	Test *pt = new Test;
	AutoPtr<Test> t(pt);
	t->fun();

	AutoPtr<Test> t2;
	t2 = t; // 赋值转移空间管理权
	t2->fun();

	system("pause");
	return 0;
}

在这里插入图片描述

2 vc版auto_ptr缺点

在调用拷贝构造或重新赋值后,空间管理权虽然发生了转移,但是仍然能通过智能指针改变或访问其所不具有空间管理权的空间的值

	int *p = new int(10);
	AutoPtr<int> q(p);
	AutoPtr<int> q2(q); // 空间管理已发生转移,交由q2管理
	*q = 100; // q已不具有空间管理权,但是仍能访问或改变原来空间的值
	cout << *q << endl;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值