3种智能指针

  • 出现智能指针的原因

用智能指针,把申请内存的工作都在接口内部实现并加以限制,把释放内存的工作交给智能指针。

  • 常见的智能指针

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是否为空指针。

  • 智能指针的实现
  • Autoptr

    代码:

#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;
}
  • Scopedptr

代码:

#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;*/
}
  • Sharedptr

    代码:

#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;
}
时间: 2024-11-03 21:00:06

3种智能指针的相关文章

四种智能指针:auto_ptr,unique_ptr,shared_ptr,weak_ptr

stl中auto_ptr,unique_ptr,shared_ptr,weak_ptr四种智能指针的使用总结 (1)auto_ptr 主要用于解决资源自动释放的问题.防止用户忘记delete掉new申请的内存空间.使用auto_ptr会在离开变量的作用域之后直接调用析构函数进行资源释放. void Function() { auto_ptr<Obj> ptr(new Obj(20)); ... if (error occur) throw exception... } 但是,这是一种被c++1

C++ 几种智能指针的简单实现

#pragma once // 智能指针 // 定义个类来封装资源的分配和释放,在构造 函数完成资源的分配和初始化,在析构函数完成资源的 // 清理,可以 保证资源的正确初始化和释放. // 这里简单实现 AutoPtr. ScopedPtr.ScopedArray以及 SharedPtr //------------------------------SmartPtr.h------------------- template<typename T> class AutoPtr //缺点 定

C++几种智能指针之间的比较

这些智能指针在设计的时候,一个关键的问题就是所有权的控制.如果把指针所指向的对象比作电视机的话,那么指针就是观众.第一个人需要看电视的时候需要打开它,没人看的时候就要保证把电视关掉. 对于std::auto_ptr,boost::shared_ptr和scoped_ptr,情况如下: 1. std::auto_ptr:auto_ptr这个种族很有趣,每次只让一个人看电视,大家可以换着看,由最后那个不想看的人关掉.当把一个auto_ptr赋值给另一个时,就好比换一个人看电视似的.总之,电视只能一个

Qt 智能指针学习(7种QT智能指针和4种std智能指针)

从内存泄露开始? 很简单的入门程序,应该比较熟悉吧 ^_^ #include <QApplication> #include <QLabel> int main(int argc, char *argv[]) { QApplication app(argc, argv); QLabel *label = new QLabel("Hello Dbzhang800!"); label->show(); return app.exec(); } 在  从 Qt

Qt 智能指针学习(7种QT的特有指针)

从内存泄露开始? 很简单的入门程序,应该比较熟悉吧 ^_^ #include <QApplication> #include <QLabel> int main(int argc, char *argv[]) { QApplication app(argc, argv); QLabel *label = new QLabel("Hello Dbzhang800!"); label->show(); return app.exec(); } 在  从 Qt

C++智能指针简单剖析

导读 最近在补看<C++ Primer Plus>第六版,这的确是本好书,其中关于智能指针的章节解析的非常清晰,一解我以前的多处困惑.C++面试过程中,很多面试官都喜欢问智能指针相关的问题,比如你知道哪些智能指针?shared_ptr的设计原理是什么?如果让你自己设计一个智能指针,你如何完成?等等--.而且在看开源的C++项目时,也能随处看到智能指针的影子.这说明智能指针不仅是面试官爱问的题材,更是非常有实用价值. 下面是我在看智能指针时所做的笔记,希望能够解决你对智能指针的一些困扰. 目录

C++ Primer笔记8_动态内存_智能指针

1.动态内存 C++中,动态内存管理是通过一对运算符完成的:new和delete.C语言中通过malloc与free函数来实现先动态内存的分配与释放.C++中new与delete的实现其实会调用malloc与free. new分配: 分配变量空间: int *a = new int; // 不初始化 int *b = new int(10); //初始化为10 string *str = new string(10, ); 分配数组空间: int *arr = new int[10];//分配的

C++智能指针剖析(下)boost::shared_ptr&amp;其他

1. boost::shared_ptr 前面我已经讲解了两个比较简单的智能指针,它们都有各自的优缺点.由于 boost::scoped_ptr 独享所有权,当我们真真需要复制智能指针时,需求便满足不了了,如此我们再引入一个智能指针,专门用于处理复制,参数传递的情况,这便是如下的boost::shared_ptr. boost::shared_ptr 属于 boost 库,定义在 namespace boost 中,包含头文件#include<boost/smart_ptr.hpp> 便可以使

第十一章:使用智能指针管理对象资源

前言 在前面的文章中,细致地分析了构造函数,拷贝构造函数,赋值运算符,析构函数这几个类中最重要函数的用法. 如果严格地遵循这些做法,可以消除绝大部分资源管理的问题. 然而,要想更灵活的使用对象中的资源,仅仅这些还不够.譬如,若你想自己控制对象资源的生命周期(不要在作用域结束的时候自动被析构掉),那就应当好好考虑下智能指针了. 有人说,智能指针是属于设计模式范畴的产物,这么说有点偏激,但也确实有点道理. 问题分析 我们假定有一个投资类Investment: 1 class Investment 2