【C++】智能指针auto_ptr

       C++的auto_ptr所做的事情,就是动态分配对象以及当对象不再需要时自动执行清理,使用std::auto_ptr,要#include <memory>。

实现代码如下:

#include <iostream>
#include <vld.h>
using namespace std;

//#define _THROW0()	throw ()抛出全部异常

template<class _Ty>
class auto_ptr
{
public:
	//typedef _Ty element_type;
	explicit auto_ptr(_Ty *_P = 0) _THROW0()
		: _Owns(_P != 0), _Ptr(_P) {}
	//explicit用来防止由构造函数定义的隐式转换
	auto_ptr(const auto_ptr<_Ty>& _Y) _THROW0()
		: _Owns(_Y._Owns), _Ptr(_Y.release()) {}
	auto_ptr<_Ty>& operator=(const auto_ptr<_Ty>& _Y) _THROW0()
	{
		if (this != &_Y)
		{
			if (_Ptr != _Y.get())
			{
				if (_Owns)
				{
					delete _Ptr;
				}
				_Owns = _Y._Owns;
			}
			else if (_Y._Owns)
			{
				_Owns = true;
			}
			_Ptr = _Y.release();
		}
		return (*this);
	}
	~auto_ptr()
	{
		if (_Owns)
		{
			delete _Ptr;
		}
	}
	_Ty& operator*() const _THROW0()
	{
		return (*get());
		//return (*_Ptr);
	}
	_Ty *operator->() const _THROW0()
	{
		return (get());
		//return (_Ptr);
	}
	_Ty *get() const _THROW0()
	{
		return (_Ptr);
	}
	_Ty *release() const _THROW0()
	{
		((auto_ptr<_Ty> *)this)->_Owns = false;
		return (_Ptr);
	}
private:
	bool _Owns;
	_Ty *_Ptr;
};

class Test
{
public:
	void Print() const
	{
		cout << "this is test!"<< endl;
	}
};

本文中重点谈论关于其的三个问题:

问题一:箭头操作符

测试代码为:

<span style="font-size:18px;"><strong>void main()
{
	Test *pt = new Test;
	auto_ptr<Test> pa(pt);
	pa->Print();
}</strong></span>

为何使用pa->Print()而不是pa->->Print()?

       箭头操作符看起来像二元操作符:接受一个对象和一个成员名,实际上,箭头操作符的右操作符并不是一个表达式,而是类成员的标识符,编译器自动将一个标识符传递给函数以获取类成员的工作。首先pa是对象,而且有operator->,调用之,返回_Ty*(Test*),为指针接下来就是调用Test的成员函数Print()。

问题二:

<span style="font-size:18px;"><strong>void main()
{
	int *p = new int(10);
	auto_ptr<int> pa(p);
	auto_ptr<int> pb(pa);

	cout << *pb << endl;
	//cout << *pa << endl;
}</strong></span>

在原始的auto_ptr实现中被注释行可以实现,这是VC库的一个缺陷,修改release()函数后代码如下:

<span style="font-size:18px;"><strong>#include <iostream>
#include <vld.h>
using namespace std;

//#define _THROW0()	throw ()抛出全部异常

template<class _Ty>
class auto_ptr
{
public:
	//typedef _Ty element_type;
	explicit auto_ptr(_Ty *_P = 0) _THROW0()
		: _Owns(_P != 0), _Ptr(_P) {}
	//explicit用来防止由构造函数定义的隐式转换
	auto_ptr(const auto_ptr<_Ty>& _Y) _THROW0()
		: _Owns(_Y._Owns), _Ptr(_Y.release()) {}
	auto_ptr<_Ty>& operator=(const auto_ptr<_Ty>& _Y) _THROW0()
	{
		if (this != &_Y)
		{
			if (_Ptr != _Y.get())
			{
				if (_Owns)
				{
					delete _Ptr;
				}
				_Owns = _Y._Owns;
			}
			else if (_Y._Owns)
			{
				_Owns = true;
			}
			_Ptr = _Y.release();
		}
		return (*this);
	}
	~auto_ptr()
	{
		if (_Owns)
		{
			delete _Ptr;
		}
	}
	_Ty& operator*() const _THROW0()
	{
		return (*get());
		//return (*_Ptr);
	}
	_Ty *operator->() const _THROW0()
	{
		return (get());
		//return (_Ptr);
	}
	_Ty *get() const _THROW0()
	{
		return (_Ptr);
	}
	_Ty *release() const _THROW0()
	{
		_Ty *_newPtr = _Ptr;
		((auto_ptr<_Ty> *)this)->_Owns = false;
	    ((auto_ptr<_Ty> *)this)->_Ptr = 0;
		return (_newPtr);
	}
private:
	bool _Owns;
	_Ty *_Ptr;
};

class Test
{
public:
	void Print() const
	{
		cout << "this is test!"<< endl;
	}
};</strong></span>

此时被注释行无法执行。

问题三:以上auto_ptr无法实现数组的应用

修改代码及测试如下:

<span style="font-size:18px;"><strong>#include <iostream>
#include <vld.h>
using namespace std;

#define N 10

//#define _THROW0()	throw ()抛出全部异常

template<class _Ty>
class auto_ptr
{
public:
	//typedef _Ty element_type;
	explicit auto_ptr(_Ty *_P = 0) _THROW0()
		: _Owns(_P != 0), _Ptr(_P) {}
	//explicit用来防止由构造函数定义的隐式转换
	auto_ptr(const auto_ptr<_Ty>& _Y) _THROW0()
		: _Owns(_Y._Owns), _Ptr(_Y.release()) {}
	auto_ptr<_Ty>& operator=(const auto_ptr<_Ty>& _Y) _THROW0()
	{
		if (this != &_Y)
		{
			if (_Ptr != _Y.get())
			{
				if (_Owns)
				{
					delete []_Ptr;
				}
				_Owns = _Y._Owns;
			}
			else if (_Y._Owns)
			{
				_Owns = true;
			}
			_Ptr = _Y.release();
		}
		return (*this);
	}
	~auto_ptr()
	{
		if (_Owns)
		{
			delete []_Ptr;
		}
	}
	_Ty& operator[](int index) const
	{
		return *(get()+index);
		//return *(_Ptr+index);
	}
	_Ty *get() const _THROW0()
	{
		return (_Ptr);
	}
	_Ty *release() const _THROW0()
	{
		_Ty *_newPtr = _Ptr;
		((auto_ptr<_Ty> *)this)->_Owns = false;
	    ((auto_ptr<_Ty> *)this)->_Ptr = 0;
		return (_newPtr);
	}
private:
	bool _Owns;
	_Ty *_Ptr;
};

void main()
{
	int *p = new int[N];
	for(int i = 0; i < N; ++i)
	{
		p[i] = 0;
	}
	auto_ptr<int> pa(p);
	auto_ptr<int> pb(p);
	pb = pa;
	for(i = 0; i < N; ++i)
	{
		cout << pb[i] << " ";
	}
	cout << endl;
}</strong></span>

以上代码如有不足之处请大家指出,谢谢大家~

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-30 03:49:00

【C++】智能指针auto_ptr的相关文章

智能指针auto_ptr详解

概述:C++中有很多种智能指针,auto_ptr就是其中的一种,该智能指针主要是为了解决"因程序异常退出发生的内存泄漏"这类问题的. 我们先来看下面的问题代码 #include<iostream> #include<memory> #include<exception> using namespace std; //一般指针的处理方式 template<typename T> class OldClass { public: OldCla

C++中的智能指针(auto_ptr)

实际上auto_ptr 只是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势,使用它不必每次都手动调用delete去释放内存.当然有利也有弊,也不是完全完美的. 本文从下面的8个方面来总结auto_ptr使用的大部分内容. 1. auto_ptr是什么? auto_ptr 是C++标准库提供的类模板,auto_ptr对象通过初始化指向由new创建的动态内存,它是这块内存的拥有者,一块内存不能同时被分给两个这样拥有者(auto_ptr).当auto_ptr对象生命

C++:浅谈c++资源管理以及对[STL]智能指针auto_ptr源码分析,左值与右值

C++:浅谈c++资源管理以及对[STL]智能指针auto_ptr源码分析 by 小威威 1. 知识引入 在C++编程中,动态分配的内存在使用完毕之后一般都要delete(释放),否则就会造成内存泄漏,导致不必要的后果.虽然大多数初学者都会有这样的意识,但是有些却不以为意.我曾问我的同学关于动态内存的分配与释放,他的回答是:"只要保证new和delete成对出现就行了.如果在构造函数中new(动态分配内存),那么在析构函数中delete(释放)就可以避免内存泄漏了!" 事实果真如此么?

【C++智能指针 auto_ptr】

<More Effective C++>ITEM M9中提到了auto_ptr,说是当异常产生的时候,怎么释放为对象分配的堆内存,避免重复编写内存释放语句. PS:这里书里面提到函数退出问题,函数退出会清理栈内存,不管是怎么正常退出还是异常退出(仅有一种例外就是当你调用 longjmp 时.Longjmp 的这个缺点是 C++率先支持异常处理的主要原因).建立在此基础上我们才把对指针的删除操作封装到一个栈对象里面.这样函数退出(异常或是正常)就会调用对象的析构函数,达到我们自动清理所封装指针指

C++智能指针 auto_ptr

C++智能指针 auto_ptr auto_ptr 是一个轻量级的智能指针, 定义于 memory (非memory.h)中, 命名空间为 std. auto_ptr 适合用来管理生命周期比较短或者不会被远距离传递的动态对象, 最好是局限于某个函数内部或者是某个类的内部. 使用方法: std::auto_ptr<int> pt(new int(10)); pt.reset(new int(11)); 成员函数 3个重要的函数: (1) get 获得内部对象的指针, 由于已经重载了()方法, 因

C++智能指针--auto_ptr指针

auto_ptr是C++标准库提供的类模板,头文件<memory>,auto_ptr对象通过初始化指向由new创建的动态内存,它是这块内存的拥有者,一块内存不能同时被分给两个拥有者.当auto_ptr对象生命周期结束时,其析构函数会将auto_ptr对象拥有的动态内存自动释放.即使发生异常,通过异常的栈展开过程也能将动态内存释放.auto_ptr不支持new数组. auto_ptr的出现,主要是为了解决"有异常抛出时发生内存泄漏"的问题.如下的简单代码是这类问题的一个简单示

C++ 智能指针auto_ptr详解

1. auto_ptr 的设计动机: 函数操作经常依照下列模式进行: 获取一些资源 执行一些动作 释放所获取的资源 那么面对这些资源的释放问题就会出现下面的两种情况: 一开始获得的资源被绑定于局部对象,那么当函数退出的时候,这些局部对象的析构函数被自动的调用,从而自动释放掉这些资源; 一开始获得的资源是通过某种显示手段获取,而且并没有绑定在任何对象身上,那么必须以显式的方式释放.这种情况常常发生在指针身上; 例子: 1 void f() 2 { 3 ClassA* ptr = new Class

【C++】智能指针auto_ptr的简单实现

//[C++]智能指针auto_ptr的简单实现 #include <iostream> using namespace std; template <class _Ty> class auto_ptr { public: auto_ptr(_Ty *_P = 0) :_Owns(_Ptr != 0), _Ptr(_P) {} auto_ptr<_Ty>(const auto_ptr <_Ty> &p):_Owns(p._Owns),_Ptr(p.r

智能指针auto_ptr源码剖析

何时我们需要智能指针? 资源所有权的共享 共享所有权是指两个或多个对象需要同时使用第三个对象的情况.这第三个对象应该如何(或者说何时)被释放?为了确保释放的时机是正确的,每个使用这个共享资源的对象必须互相知道对方,才能准确掌握资源的释放时间.从设计或维护的观点来看,这种耦合是不可行的.更好的方法是让这些资源所有者将资源的生存期管理责任委派给一个智能指针.当没有共享者存在时,智能指针就可以安全地释放这个资源了. 要编写异常安全的代码时 异常安全简单地说就是在异常抛出时没有资源泄漏并保证程序状态的一

C/C++——跟我重写智能指针auto_ptr模版类

第一次使用auto_ptr的时候感觉很好用,但是对内部原理根本不懂,心里不知道这东西到底是个什么东东,总是感觉这东东比较陌生.今天有时间来简单实现一下该类模版auto_ptr,实现了该模版类的主要功能,可以让大家了解一下这个东东内部到底是个什么情况. 栈对象和堆对象的区别: 首先,看一下两种类对象的区别,一个是在栈上分配空间,另一个是在堆上分配空间. 如果看到这里,你不清楚堆和栈的区别.那我也不解释了,自行Google..(如果你想baidu也不拦你) 1.先测试栈上分配的对象 #include