Boost智能指针库SmartPointers:作用域指针/数组、共享指针/数组、弱指针、介入式指针、指针容器简单介绍

导语

智能指针的原理基于RAII机制资源申请即初始化。智能指针确保在任何情况下,动态分配的内存都能得到正确释放,避免程序因内存不足等原因造成的崩溃出现,即使程序因为异常中断也不必担心。
用一个动态分配的对象的地址初始化智能指针。 智能指针确保资源离开作用域后会被自动释放。

//简单理解RAII机制
class myClass
{
    myClass() {    myBuf = new int[1024];    }
    ~myClass() { 
        if(nullptr != myBuf) {
            delete myBuf;
            myBuf = nullptr;
        }
    }

    void usePointer() { //usePointer }
private:
    int* myBuf;
};

boost提供的智能指针包括如下,除如下所示的头文件,也可以使用<boost/smart_ptr.hpp>包含所有用到的智能指针。

智能指针类型说明所在头文件
boost::scope_ptr作用域指针,独占一个动态分配的对象<boost/scoped_ptr.hpp>
boost::scoped_array作用域数组,是否用方式类似作用域指针,不同在于作用域数组必须通过动态分配的数组来初始化初始化<boost/scoped_array.hpp>
boost::shared_ptr共享指针,同std::shared_ptr,基本类似作用域指针,与作用域指针不同在于不一定要独占一个对象<boost/shared_ptr.hpp>
boost::shared_array共享数组,类似共享指针,不同共享数组必须通过动态分配的数组的地址来初始化。<<boost>shared_array.hpp>
boost::weak_ptr弱指针,配合共享指针一起使用<boost/weak_ptr.hpp>
boost::intrusive_ptr介入式指针,同共享指针,但需要程序员记录引用某个对象的共享指针的数量<boost/intrusive_ptr.hpp>
boost::ptr_vector指针容器,管理动态分类的对象<boost/ptr_container/ptr_vector.hpp>

1、作用域指针–boost::scoped_ptr

类boost::scoped_ptr定义在<boost/scoped_ptr.hpp>中。
一个作用域指针独占一个动态分配的对象,对应的类名是boost::scoped_ptr。

作用域指针不能传递它包含的对象的所有权到另一个作用域指针。
在不需要所有权传递的时候应该优先使用boost::scoped_ptr。
可以通过类似于普通指针的接口来访问boost::scoped_ptr的对象。

boost::scoped_ptr的成员函数有:

  • 重载操作符:operator*()、operator->、operator bool();
  • 返回对象的地址:get();
  • 重新初始化智能指针:reset(),该函数会先释放所包含的对象,然后使用新创建的对象复制。

boost::scoped_ptr的析构函数使用delete操作符释放所包含的对象,所以不能用动态分配的数组来初始化,可以使用作用域指针boost::scoped_array类。

2、作用域数组–boost::scoped_array

类boost::scoped_array定义在<boost/scoped_array.hpp>中。

使用方式与作用域指针相似,不同点在于作用域数组的析构函数使用delete[]操作符释放包含的对象,所以boost::scoped_array对象必须通过动态分配的数组来初始化。

boost::scoped_array的常用成员函数有:

  • 重载操作符:operator[]()、operator bool(),所以可以通过operator[]访问数组中特定的元素;
  • 返回对象的地址:get();
  • 重新初始化智能指针:reset(),该函数会先释放所包含的对象,然后使用新创建的对象复制。

3、共享指针–boost::shared_ptr

类boost::shared_ptr定义在<boost/shared_ptr>

boost::shared_ptr与memory中定义的std::shared_ptr类似。
boost::shared_ptr基本类似boost::scoped_ptr,不同点在于boost::shared_ptr不一定要独占一个对象,可以和其它boost:;shared_ptr类型的智能指针共享所有权。共享所有权后,当引用对象的最后一个智能指针销毁后,对象才会被释放

所有权可以在boost::shared_ptr之间共享,任何一个共享指针都可以复制,这样就可以在标准容器里存储智能指针,而std::auto_ptr不能存储在标准容器钟,因为在std::auto_ptr在拷贝的时候传递了所有权。

boost::shared_ptr常用的成员函数有:

  • 重载操作符:operator*()、operator->()、operator bool();
  • 获取和初始化所包含对象的地址的函数:get()和reset();

默认情况下boost::shared_ptr使用delete销毁所含的对象,可以在构造函数的第二个参数指定用什么方式销毁所含的对象。
示例:

		boost::shared_ptr<void> hins(OpenProcess(PROCESS_SET_INFORMATION,FALSE,GetCurrentProcessId()),CloseHandle);
		SetPriorityClass(hins.get(),HIGH_PRIORITY_CLASS);

构造函数的第二个参数是 Windows API 函数 CloseHandle()。 当变量 hins 超出它的作用域时,调用CloseHandle()来销毁所含的对象。 为了避免编译错误,该函数只能带一个 HANDLE 类型的参数, CloseHandle() 正好符合要求,CloseHandle()会在共享指针超出它的作用域时自动调用。

4、共享数组–boost::shared_array

类boost::shared_array定义在<boost/shared_array>
共享数组的行为类似于共享指针,不同点在于共享数组析构时,默认使用
delete[]操作符释放包含的对象。所以共享数组必须通过动态分配的数组的地址来初始化。

boost::shared_array提供的成员函数有:

  • 重载运算符:operator[]()、operator bool();
  • 获取和初始化所包含对象的地址的函数:get()和reset();

5、弱指针–boost::weak_ptr

类boost::weak_ptr定义在<boost/weak_ptr.hpp>

弱指针需要配合共享指针一起使用。当一个函数需要一个由共享指针所管理的对象,而这个对象的生存期又不依赖于这个函数时,就可以使用弱指针。只要程序中还有一个共享指针掌管着这个对象,函数就可以使用该对象。 如果共享指针复位了,就算函数里能得到一个共享指针,对象也不存在了。

boost::weak_ptr通过boost::shared_ptr来初始化,初始化之后基本上只提供一个有用的方法:lock(),lock()的返回boost::shared_ptr与用来初始化弱指针的共享指针共享所有权。

6、介入式指针–boost::intrusive_ptr

类boost::intrusive_ptr定义在<boost/intrusive_ptr.hpp>
介入式指针的工作方式和共享指针完全一样。不同在于,对介入式指针来说,程序员就得自己来做记录。 对于框架对象来说这就特别有用,因为它们记录着自身被引用的次数。

7、指针容器–boost::shared_ptr

boost::ptr_vector 类的定义在 <boost/ptr_container/ptr_vector.hpp> 中
多数情况下,智能指针对象要存储在容器中。
然而现实是反复声明boost::shared_ptr需要更多的输入,另外boost::shared_ptr拷进、拷出,或者在容器内部做拷贝需要频繁的增加或减少内部引用计数,导致效率不高,boost C++库提供指针容器专门管理动态分配的对象。
boost::ptr_vector独占它所包含的对象,因而容器之外的共享指针不能共享所有权,这跟std::vector<boost::shared_ptr<int> >相反。

除了boost::ptr_vector之外,专门用于管理动态分配对象的容器还包括:

  • boost::ptr_deque
  • boost::ptr_list
  • boost::ptr_set
  • boost::ptr_map
  • boost::ptr_unordered_set
  • boost::ptr_unordered_map

使用示例参考:

const int g_width = 8000;
const int g_height = 6000;
struct MyStruct
{
	float fR[g_width*g_height / 4];
	float fGR[g_width*g_height / 4];
	float fGB[g_width*g_height / 4];
	float fB[g_width*g_height / 4];
}LSCMat;

void test_smart_pointers(){

	// 作用域指针 数组
	{
		MyStruct *p = NULL;
		boost::scoped_ptr<MyStruct> scopedptr(new MyStruct);
		p = scopedptr.get();
		//boost::scoped_ptr<MyStruct> scopedptr_other(scopedptr);  // 该语句错误,作用域指针不能共享所有权
		//scopedptr_other = scopedptr;  // 该语句错误
		scopedptr.reset(new MyStruct);
		p = scopedptr.get();


		boost::scoped_array<int> scoArray(new int[g_width*g_height]);
		int* pbuf = scoArray.get();
		printf("\nscoArray = 0x%x,\tpbuf = 0x%x,\tpbuf[0] = %d", scoArray, pbuf, pbuf[0]);
		memset(pbuf, 255, g_width*g_height*sizeof(int));
		scoArray.reset(new int[g_width]);
		//printf("\nscoArray = 0x%x,\tpbuf = 0x%x,\tpbuf[0] = %d", scoArray, pbuf, pbuf[0]);  // 错误,pbuf已经被释放,不能再访问pbuf[0]
		printf("\nscoArray = 0x%x,\tpbuf = 0x%x", scoArray, pbuf);

	}

	
	// 共享指针、数组
	{
		boost::shared_ptr<MyStruct> shareptr(new MyStruct);
		boost::shared_ptr<MyStruct> shareptr_other(shareptr);
		
		shareptr_other.get()->fR[0] = 3.14;
		printf("\nshareptr = 0x%x,\tshareptr_other = 0x%x,\tshareptr.get()->fR[0] = %g", shareptr, shareptr_other, shareptr.get()->fR[0]);

		boost::shared_array<float> sharArray(new float[g_width*g_height]);
		boost::shared_array<float> sharArr_other(sharArray);
		boost::shared_array<float> other1(sharArray);
		boost::shared_array<float> other2(sharArray);
		boost::shared_array<float> other3(sharArray);
		printf("\nshareptr = 0x%x, \nother = 0x%x,\nother1 = 0x%x, \nother2 = 0x%x, \nother3 = 0x%x", sharArray, sharArr_other, other1, other2, other3);
		float *p = sharArray.get();
		p[0] = 3.14;
		printf("\nsharArray = 0x%x,\tsharArr_other = 0x%x,\tsharArr_other[0] = %g", sharArray, sharArr_other, sharArr_other[0]);
	}

	// 指针容器
	{
		boost::ptr_vector<int> v;
		v.push_back(new int(1));
		v.push_back(new int(2));
		int p = v.at(0);
		printf("p = %d", p);
	}
}

本文参考:Highscore - Boost C++ 库 - 智能指针

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值