栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

类boost::scoped_ptr定义在中。
一个作用域指针独占一个动态分配的对象,对应的类名是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定义在中。

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

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

  • 重载操作符:operator[]()、operator bool(),所以可以通过operator[]访问数组中特定的元素;
  • 返回对象的地址:get();
  • 重新初始化智能指针:reset(),该函数会先释放所包含的对象,然后使用新创建的对象复制。
3、共享指针–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 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定义在
共享数组的行为类似于共享指针,不同点在于共享数组析构时,默认使用delete[]操作符释放包含的对象。所以共享数组必须通过动态分配的数组的地址来初始化。

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

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

类boost::weak_ptr定义在

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

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

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

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

7、指针容器–boost::shared_ptr

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

除了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 scopedptr(new MyStruct);
		p = scopedptr.get();
		//boost::scoped_ptr scopedptr_other(scopedptr);  // 该语句错误,作用域指针不能共享所有权
		//scopedptr_other = scopedptr;  // 该语句错误
		scopedptr.reset(new MyStruct);
		p = scopedptr.get();


		boost::scoped_array 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 shareptr(new MyStruct);
		boost::shared_ptr 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 sharArray(new float[g_width*g_height]);
		boost::shared_array sharArr_other(sharArray);
		boost::shared_array other1(sharArray);
		boost::shared_array other2(sharArray);
		boost::shared_array 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 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++ 库 - 智能指针

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号