boost 智能指针 shared_ptr

boost 库中不单单这一种智能指针类型。但只有 shared_ptr 是最接近普通指针的一种智能指针,他具有一些非常良好的特性,比如计数器等等,使用 shared_ptr 可以让我们不用花费精力在内存回收上。其他的一些指针与 shared_ptr 的区别如下表:

2015-06-14_232943

本文主要介绍 shared_ptr 的一些特性,以后如果你使用到 boost 库,那么用到这个智能指针也会是最多的。

1、boost::shared_ptr实现了计数引用:

它包装了new操作符在堆上分配的动态对象,但它实现了引用计数,可以自由的拷贝和赋值,在任意地方共享它。当引用计数为0时,它会自动删除被包装的动态分配的对象。

2、boost::shared_ptr不需要手动的调用类似release方法:

它不像侵入式实现的智能指针一样需要手动的调用类似release方法,全部用由shared_ptr内部的计数器自动增减,这一点是非常有用的。(COM的IUnknow接口以及boost::intrusive_ptr<T>都是基于侵入式设计的智能指针,需要手动调用类似release方法)

3、boost::shared_ptr支持所有权转移:

并且可以安全的存储在stl标准容器中,是在stl容器存储指针的标准解法。例如std::vector<int*> IntVec,使用shared_ptr方式为std::vector<boost::shared_ptr<int> > IntptrVec.

4、boost::shared_ptr的代码操作和注意事项

#include <iostream>
#include <boost/shared_ptr.hpp>

using namespace std;

class MyClass
{
public:
	void func()
	{
		cout << "MyClass func" << endl;
	}
};

class Mem_malloc
{
public:
	Mem_malloc()
	{
		m_int = (int*)malloc(sizeof(int) * 1024 * 1024 * 100); // 400M
	}
	~Mem_malloc()
	{
		free(m_int);
	}
private:
	int* m_int;
};

int main(int argc, char* argv[])
{
	// 两种构造
	boost::shared_ptr<int> ptr;
	boost::shared_ptr<int> ptr_arr(new int(100));

	// 与普通指针相差无几
	int a = 111;
	int* pA = &a;
	cout << "*pA = " << *pA << endl;
	cout << "*ptr_arr = " << *ptr_arr << endl;

	// 操作对象
	boost::shared_ptr<MyClass> ptr_obj;
	boost::shared_ptr<MyClass> ptr_MyClass(new MyClass());
	ptr_obj = ptr_MyClass;
	ptr_obj->func();

	// 智能指针避免普通指针和智能指针混用
	// 防止智能指针计数器为0将内存释放后,普通指针就变了野指针。
	int* p_int001 = new int(100);
	int* p_int002 = p_int001;
	//boost::shared_ptr<int> ptr_int003 = p_int002;		// 错误的,不能混用

	boost::shared_ptr<int> ptr_int004(new int(100));
	//int* p_int005 = ptr_int004;						// 错误的,不能混用

	// 引用计数
	boost::shared_ptr<MyClass> ptr_obj001(new MyClass());
	cout << ptr_obj001.use_count() << endl;
	boost::shared_ptr<MyClass> ptr_obj002 = ptr_obj001;
	// 指向同一对象时,两个智能指针的引用计数都会增加
	cout << ptr_obj002.use_count() << endl;
	cout << ptr_obj001.use_count() << endl;

	{
		// 新作用域指向同一对象,同样会自增引用计数
		boost::shared_ptr<MyClass> ptr_obj003 = ptr_obj001;
		cout << "new function" << endl;
		cout << "ptr_obj003.use_count() = " << ptr_obj003.use_count() << endl;
		cout << "ptr_obj002.use_count() = " << ptr_obj002.use_count() << endl;
		cout << "ptr_obj001.use_count() = " << ptr_obj001.use_count() << endl;
	}

	// 离开作用域后,原作用域内的引用计数会被减去
	cout << "exit function" << endl;
	cout << "ptr_obj002.use_count() = " << ptr_obj002.use_count() << endl;
	cout << "ptr_obj001.use_count() = " << ptr_obj001.use_count() << endl;

	// 测试智能指针是否会释放内存
	{
		cout << "准备分配内存" << endl;
		// 这个过程打开任务管理器,按下任意键后看内存的变化
		system("pause");
		boost::shared_ptr<Mem_malloc> ptr_obj004(new Mem_malloc());
		cout << "准备释放内存" << endl;
		// 离开作用域后再看内存的变化
		system("pause");
		// 离开作用域后会自动释放ptr_obj004指向的内存,在任务管理器中,可以明显的看到我们进程内存的变化
	}

	return 0;
}

 

说说你的想法