智能指针

  • RAII(Resource Acquisition Is Initialization)

资源分配即初始化,定义一个类来封装资源的分配和释放,在构造函数完成资源的分配和初始化,在析构函数完成资源的清理,可以保证资源的正确初始化和释放。

-------------------------------------------------------------------------------------------

为什么要有智能指针呢?

智能指针的存在是为了防止我们在大型项目中忘记释放空间而导致很恐怖的空间浪费,通过RAII,实现智能指针的类实现,而完成指针的自动释放。

STL--auto_ptr

Boost库的智能指针(ps:新的C++11标准中已经引入了unique_ptr/shared_ptr/weak_ptr)

auto_ptr:这个指针是现在是不提倡使用的,理由如下:

auto_ptr对象被拷贝或者被赋值后,已经失去了对原指针的所有权,此时,对这个auto_ptr的读取操作是不安全的。出现在将auto_ptr作为函数参数按值传递,因为在函数调用过程中在函数的作用域中会产生一个局部的临时auto_ptr对象来接收传入的 auto_ptr(拷贝构造),这样,传入的实参auto_ptr的对其指针的所有权转移到了临时auto_ptr对象上,临时auto_ptr在函数退出时析构,所以当函数调用结束,原实参所指向的对象已经被删除了。

scoped_ptr:就是防拷贝的RAII智能指针实现。

shared_ptr:就是存在引用计数,浅拷贝的智能指针实现

weak_ptr:就是解决当shared_ptr出现循环引用时解决而出现的弱指针。

-------------------------------------------------------------------------------------------------------------------

循环引用问题:

强引用和弱引用

一个强引用当被引用的对象活着的话,这个引用也存在(就是说,当至少有一个强引用,那么这个对象就不能被释放)。boost::share_ptr就是强引用。

相对而言,弱引用当引用的对象活着的时候不一定存在。仅仅是当它存在的时候的一个引用。弱引用并不修改该对象的引用计数,这意味这弱引用它并不对对象的内存进行管理,在功能上类似于普通指针,然而一个比较大的区别是,弱引用能检测到所管理的对象是否已经被释放,从而避免访问非法内存。

----------------------------------------------------------------------------------------------------------------------------

下面是简单的代码实现:

#pragma once
#include <assert.h>

// RAII

template<class T>
class AutoPtr
{
public:
	explicit AutoPtr(T* ptr)
		:_ptr(ptr)
	{}

	~AutoPtr()
	{
		if (_ptr)
		{
			delete _ptr;
			_ptr = NULL;
		}
	}

	AutoPtr(AutoPtr<T>& ap)
		:_ptr(ap._ptr)
	{
		ap._ptr = NULL;
	}

	AutoPtr& operator=(AutoPtr<T>& ap)
	{
		if(&ap != this)
		{
			if (_ptr && _ptr != ap._ptr)
			{
				delete _ptr;
			}

			_ptr = ap._ptr;
			ap._ptr = NULL;
		}

		return *this;
	}

	T& operator*()
	{
		assert(_ptr);
		return *_ptr;
	}

	T* operator->()
	{
		return _ptr;
	}

	T* GetPtr()
	{
		return _ptr;
	}

	bool operator==(const AutoPtr<T>& ap)
	{
		return _ptr == ap._ptr;
	}

protected:
	T* _ptr;
};

// C++98/03
// 
void Test1()
{
	AutoPtr<int> ap1(new int(1));
	//AutoPtr<int> ap1 = new int(1);

	AutoPtr<int> ap2(ap1);

	cout<<*ap1<<endl;

	AutoPtr<int> ap3(new int(2));
	ap3 = ap1;
}

// Boost
template<class T>
class ScopedPtr
{
public:
	ScopedPtr(T* ptr)
		:_ptr(ptr)
	{}

	~ScopedPtr()
	{
		if (_ptr)
		{
			delete _ptr;
			_ptr = NULL;
		}
	}

	T& operator*()
	{
		//assert(_ptr);
		return *_ptr;
	}

	T* operator->()
	{
		return _ptr;
	}

	T* GetPtr()
	{
		return _ptr;
	}

	// 只声明不实现
private:
	ScopedPtr(const ScopedPtr<T>& ap);
	ScopedPtr& operator=(const ScopedPtr<T>& ap);

protected:
	T* _ptr;
};

void Test2()
{
	ScopedPtr<int> ap1 = new int(1);
	//ScopedPtr<int> ap2(ap1);
}

// 引用计数->
template<class T>
class SharedPtr
{
public:
	SharedPtr(T* ptr)
		:_ptr(ptr)
		,_count(new int(1))
	{}

	SharedPtr(SharedPtr<T>& sp)
		:_ptr(sp._ptr)
		,_count(sp._count)
	{
		//++_count[0];
		++(*_count);
	}

	SharedPtr& operator=(const SharedPtr<T>& sp)
	{
		//if (this != &sp)
		if (_ptr != sp._ptr)
		{
			_Release();

			_ptr = sp._ptr;
			_count = sp._count;
			++(*_count);
		}

		return *this;
	}

	void _Release()
	{
		if (--(*_count) == 0)
		{
			cout<<"Delete"<<endl;
			delete _count;
			delete _ptr;
		}
	}

	~SharedPtr()
	{
		_Release();
	}

private:
	T* _ptr;
	int* _count;
};

struct AA
{
	AA()
	{
		cout<<"AA()"<<endl;
	}

	~AA()
	{
		cout<<"~AA()"<<endl;
	}

	int a;
};

//template<class T>
//class SharedArray
//{
//public:
//	//operator-> X
//	//operator*  X
//	T& operator [](size_t index)
//	{
//		return _ptr[index];
//	}
//
//	~SharedArray()
//	{
//		if (--(*_count) == 0)
//		{
//			delete[] _ptr;
//			delete _count;
//		}
//	}
//private:
//	T* _ptr;
//	int* _count;
//};

void Test3()
{
	SharedPtr<AA> sp1(new AA[10]);
	SharedPtr<AA> sp2(sp1);

	SharedPtr<int> sp3(new int);
	//SharedPtr<int> sp4(sp3);

	//sp2 = sp3;
}

以上。

时间: 2024-08-01 10:42:48

智能指针的相关文章

智能指针的原理和简单实现

什么是智能指针? 智能指针实质上是一个类,定义一个类来封装资源的分配和释放.这个类的构造函数中传入一个指针,完成资源的分配和初始化.在析构函数中释放传入的该指针,完成资源的释放. 为什么要用智能指针? 智能指针就是智能,自动化的管理指针所指向的动态资源. 例如以下情况:代码中经常会忘记释放动态开辟的内存资源,导致内存泄露. // case1 void Test2() {  int* p1 = new int(2);  bool isEnd = true;  //...  if (isEnd)  

实战c++中的智能指针unique_ptr系列-- 使用std::unique_ptr代替new operator(错误:‘unique_ptr’ is not a member of ‘std’)

写了很多篇关于vector的博客,其实vector很便捷,也很简单.但是很多易错的问题都是vector中的元素为智能指针所引起的.所以决定开始写一写关于智能指针的故事,尤其是unique_ptr指针的故事. 这是个开始,就让我们使用std::unique_ptr代替new operator吧! 还是用程序说话: #include<iostream> int main() { while (true) int *x = new int; } 看下任务管理器中的内存: 此时使用智能指针unique

C++智能指针简单剖析

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

boost智能指针使用

#include <iostream> #include <tr1/memory> #include <boost/scoped_ptr.hpp> //scoped_ptr还不属于tr1 #include <boost/scoped_array.hpp> //scored_array也不属于tr1 #include <boost/shared_array.hpp> //shared_array也不属于tr1 class CTest { publi

webkit智能指针 - RefPtr, PassRefPtr

历史 2005年之前,Webkit中很多对象都采用引用计数的方式.它们通过继承RefCounted]类模板来实现这种模式.RefCounted主要是实现了ref()和deref()两个函数.在需要引用对象时要调用ref()增加引用计数,在不再需要对象时,要调用deref()函数减少引用计数.ref()和deref()需要成对出现.这和使用new/delete一样,多调用.少调用.没调用的问题总是时有发生.如果能由编译器自动完成ref, deref的调用,C/C++编程的bug至少也可以减少一半以

智能指针tr1::shared_ptr、boost::shared_ptr使用

对于tr1::shared_ptr在安装vs同时会自带安装,但是版本较低的不存在.而boost作为tr1的实现品,包含 "Algorithms Broken Compiler Workarounds Concurrent Programming Containers Correctness and Testing Data Structures Domain Specific Function Objects and Higher-order Programming Generic Progra

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++之智能指针20170920

/******************************************************************************************************************/ 一.C++智能指针_自己实现智能指针 1.使用局部变量结合new的方式,防止new导致的内存泄漏 class sp { private: Person *p; public: sp() : p(0) {}//表明sp的构造函数 继承person的无参构造函数 sp(

智能指针简介

智能指针用于解决常规指针所带来的内存泄露.重复释放.野指针等内存问题.智能指针基于这样的事实得以发挥作用:定义在栈中的智能指针,当超出其作用域时,会自动调用它的析构函数,从而可以释放其关联的内存资源. 之前C++标准库中定义的智能指针std::auto_ptr<T>,因其设计存在缺陷,所以已不再推荐使用.C++11引入了新的智能指针:unique_ptr.shared_ptr和weak_ptr. 一:unique_ptr unique_ptr类似于auto_ptr.两个unique_ptr实例

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> 便可以使