3种智能指针

发布时间:2020-08-03 19:11:34 作者:2013221
来源:网络 阅读:391
     用智能指针,把申请内存的工作都在接口内部实现并加以限制,把释放内存的工作交给智能指针。

     1.你知道智能指针吗?智能指针的原理。
     2.常用的智能指针。
     3.智能指针的实现。

  1答案:智能指针是一个类,这个类的构造函数中传入一个普通指针,析构函数中释放传入的指针。智能指针的类都是栈上的对象,所以当函数(或程序)结束时会自动被释放,

     2, 最常用的智能指针: 

      1)std::auto_ptr,有很多问题。 不支持复制(拷贝构造函数)和赋值(operator =),但复制或赋值的时候不会提示出错。因为不能被复制,所以不能被放入容器中。

     2) C++11引入的unique_ptr(scoped_ptr), 也不支持复制和赋值,但比auto_ptr好,直接赋值会编译出错。实在想赋值的话,需要使用:std::move。

      例如:

          std::unique_ptr<int> p1(new int(5));
          std::unique_ptr<int> p2 = p1; // 编译会出错
          std::unique_ptr<int> p3 = std::move(p1); // 转移所有权, 现在那块内存归p3所有, p1成为无效的指针.

      3) C++11或boost的shared_ptr,基于引用计数的智能指针。可随意赋值,直到内存的引用计数为0的时候这个内存会被释放。

      4)C++11或boost的weak_ptr,弱引用。 引用计数有一个问题就是互相引用形成环,这样两个指针指向的内存都无法释放。需要手动打破循环引用或使用weak_ptr。顾名思义,weak_ptr是一个弱引用,只引用,不计数。如果一块内存被shared_ptr和weak_ptr同时引用,当所有shared_ptr析构了之后,不管还有没有weak_ptr引用该内存,内存也会被释放。所以weak_ptr不保证它指向的内存一定是有效的,在使用之前需要检查weak_ptr是否为空指针。

#pragma once

template<class T>
class Autoptr
{
public:
	Autoptr()
		:_ptr(NULL)
	{}
	Autoptr(T *ptr)
		:_ptr(ptr)
	{}
	Autoptr(Autoptr<T>& a)
		:_ptr(a._ptr)
	{
		delete _ptr;
		a._ptr = NULL;
	}
	~Autoptr()
	{
		if (_ptr)
		{
			delete _ptr;
			_ptr = NULL;
		}
	}
	Autoptr<T>& operator=(Autoptr<T>&a)
	{
		if (this != &a)
		{
			delete _ptr;
			_ptr = a._ptr;
			a._ptr = NULL;
		}
		return *this;
	}
	T& operator*()
	{
		return *_ptr;
	}
	T* Getptr()
	{
		return _ptr;
	}

protected:
	T *_ptr;
};
void Autoptrtest()
{
	int *a = new int(5);
	Autoptr<int> ap1(a);
	cout << *ap1 << endl;
	cout << ap1.Getptr() << endl;
	Autoptr<int> ap2(ap1);
	cout << *ap2 << endl;
	cout << ap2.Getptr() << endl;
	cout << ap1.Getptr() << endl;
	Autoptr<int> ap3;
	ap3 = ap2;
	cout << *ap3 << endl;
	cout << ap3.Getptr() << endl;
	cout << ap2.Getptr() << endl;
}

   代码:

#pragma once
template<class T>
class Scopedptr
{
public:
	Scopedptr()
		:_ptr(NULL)
	{}
	Scopedptr(T *data)
		:_ptr(data)
	{}
	~Scopedptr()
	{
		if (_ptr)
		{
			delete _ptr;
			_ptr = NULL;
		}
	}
	T& operator*()
	{
		return *_ptr;
	}
	T* Getptr()
	{
		return _ptr;
	}
protected://加上protected可以防止使用者在类之外定义拷贝构造和运算符的重载函数 
	Scopedptr<T>(const Scopedptr<T>&sp); //不让使用者使用拷贝,可以防止拷贝,所以只声明不定义
	Scopedptr<T>& operator=(const Scopedptr<T>&sp);
private:
	T *_ptr;
};
void Scopedptrtest()
{
	int *a = new int(5);
	Scopedptr<int> ap1(a);
	cout << *ap1 << endl;
	cout << ap1.Getptr() << endl;
	/*Scopedptr<int> ap2(ap1);
	cout << *ap2 << endl;
	Scopedptr<int> ap3;
	ap3 = ap2;
	cout << *ap3 << endl;
	cout << ap3.Getptr() << endl;
	cout << ap2.Getptr() << endl;*/
}
#pragma once
template<class T>
class Sharedptr
{
public:
	Sharedptr()
		:_ptr(NULL)
		, _pcount(new int(1))
	{}
	Sharedptr(T *ptr)
		:_ptr(ptr)
		, _pcount(new int(1))
	{}
	Sharedptr(const Sharedptr<T>& sp)
		:_ptr(sp._ptr)
		, _pcount(sp._pcount)
	{
		++(*_pcount);
	}
	~Sharedptr()
	{
		if (_ptr)
		{
			if (--(*_pcount)==0)
			{
				delete _ptr;
				delete _pcount;
				_ptr = NULL;
				_pcount = NULL;
			}
			_ptr = NULL;
		}
	}
	Sharedptr<T>& operator=(const Sharedptr<T> &sp)
	{
		if (this != &sp)
		{
			if (--(*_pcount) == 0)
			{
				delete _ptr;
				delete _pcount;
				_ptr = NULL;
				_pcount = NULL;
			}
			_ptr = sp._ptr;
			_pcount = sp._pcount;
			++(*_pcount);
		}
		return *this;
	}
private:
	T* _ptr;
	int *_pcount;
};
void Sharedptrtest()
{
	int *a = new int(5);
	Sharedptr<int> ap1(a);
	Sharedptr<int> ap2(ap1);
	Sharedptr<int> ap3;
	ap3 = ap2;
}


推荐阅读:
  1. 智能指针类模板(五十)
  2. c++智能指针怎么用

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

指针 智能

上一篇:ASP.NET Web API 控制器创建过程(二)

下一篇:win10装双系统图文教程

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》