当前位置:文档之家› Boost 中的智能指针

Boost 中的智能指针

Boost 中的智能指针
Boost 中的智能指针

Boost 中的智能指针

这篇文章主要介绍 boost中的智能指针的使用。

内存管理是一个比较繁琐的问题,C++中有两个实现方案:垃圾回收机制和智能指针。垃圾回收机制因为性能等原因不被C++的大佬们推崇,而智能指针被认为是解决C++内存问题的最优方案。

1. 定义

一个智能指针就是一个C++的对象,这对象的行为像一个指针,但是它却可以在其不需要的时候自动删除。注意这个“其不需要的时候”,这可不是一个精确的定义。这个不需要的时候可以指好多方面:局

部变量退出函数作用域、类的对象被析构……。所以boost定义了多个不同的智能指针来管理不同的场景。

shared_ptr 内部维护一个引用计数器来判断此指针是不是需要被释放。是

boost中最常用的智能指针了。

scoped_ptr 当这个指针的作用域消失之后自动释放

intrusive_ptr 也维护一个引用计数器,比shared_ptr有更好的性能。但是

要求T自己提供这个计数器。

weak_ptr 弱指针,要和shared_ptr 结合使用

shared_array 和shared_ptr相似,但是访问的是数组

scoped_array 和scoped_ptr相似,但是访问的是数组

2. Boost::scoped_ptr

scoped_ptr 是boost中最简单的智能指针。scoped_ptr的目的也是很简单,当一个指针离开其作用域时候,释放相关资源。特别注意的一定就是scoped_ptr 不能共享指针的所有权也不能转移所有权。

也就是说这个内存地址就只能给的声明的变量用,不能给其他使用。

下面是scoped_ptr的几个特点:

?scoped_ptr的效率和空间的消耗内置的指针差不多。

?scoped_ptr不能用在标准库的容器上。(用shared_ptr代替)

?scoped_ptr 不能指向一块能够动态增长的内存区域(用scoped_array代替)

1class test

2{

3public:

4void print()

5 {

6 cout << "test print now" <

7 }

8};

9int _tmain(int argc, _TCHAR* argv[])

10{

11 boost::scoped_ptr x(new test);

12 x->print();

13return0;

14}

3.Boost::shared_ptr

shared_ptr 具有如下几个特点:

?在内部维护一个引用计数器,当有一个指针指向这块内存区域是引用计数+1,反之-1,如果没有任何指针指向这块区域,引用计数器为0,释放内存区域。

?可以共享和转移所有权。

?可以被标准库的容器所使用

?不能指向一块动态增长的内存(用share_array代替)

我们可以看下如下例子:

1int _tmain(int argc, _TCHAR* argv[])

2{

3 boost::shared_ptr ptr_1(new test);

4 ptr_1->print();//引用计数为1

5 boost::shared_ptr ptr_2 = ptr_1;

6 ptr_2->print();//引用计数为2

7 ptr_1->print();// 引用计数还是为2

8return0;

9}

4. Boost::intrusive_ptr

intrusive_ptr 的主要和share_ptr一样,对比share_ptr,其效率更高,但是需要自己维护一个引用计数器,这里不做详细介绍。

5. Boost::weak_ptr

weak_ptr 就是一个弱指针。weak_ptr 被shared_ptr控制,它可以通过share_ptr的构造函数或者lock成员函数转化为share_ptr。

weak_ptr的一个最大特点就是它共享一个share_ptr的内存,但是无论是构造还是析构一个weak_ ptr 都不会影响引用计数器。

1int _tmain(int argc, _TCHAR* argv[])

2{

3 boost::shared_ptr sharePtr(new test);;

4 boost::weak_ptr weakPtr(sharePtr);

5//weakPtr 就是用來保存指向這塊內存區域的指針的

6 //干了一大堆其他事情

7 boost::shared_ptr sharePtr_2 = weakPtr.lock();

8if (sharePtr_2)

9 sharePtr_2->print();

10return0;

11}

6. Boost::shared_array 和Boost::scoped_array

>

前面提到过shared_ptr和scoped_ptr不能用于数组的内存(new []),所以shared_array和s coped_array就是他们的代替品。我们可以看下shared_array的用法

1int _tmain(int argc, _TCHAR* argv[])

2{

3const int size = 10;

4 boost::shared_array a(new test[]);

5for (int i = 0; i < size; ++i)

6 a[i].print();

7return0;

8}

7. 使用智能指针的几个注意点

下面是几个使用智能指针需要注意的地方:

?声明一个智能指针的时候要立即给它实例化,而且一定不能手动释放它。

?…_ptr 不是T* 类型。所以:

a: 声明的时候要…_ptr 而不是….._ptr

b:不能把T* 型的指针赋值给它

c: 不能写ptr=NULl, 而用ptr.reset()代替。

?不能循环引用。

?不要声明临时的share_ptr,然后把这个指针传递给一个函数

8. 总结

智能指针使用上还是比较简单的,而且能比较有效得解决C++内存泄露的问题,各位使用C++的童鞋赶快用起来吧。

auto_ptr智能指针

C++智能指针(auto_ptr)详解 (2012-04-19 23:29:16) 转载▼ 标签: 分类:软件程序 c auto_ptr 智能指针 内存 it 智能指针(auto_ptr)这个名字听起来很酷是不是?其实auto_ptr 只是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势,但也有其局限。本文总结的8个问题足以涵盖auto_ptr的大部分内容。 1. auto_ptr是什么? auto_ptr 是C++标准库提供的类模板,auto_ptr对象通过初始化指向由new创建的动态内存,它是这块内存的拥有者,一块内存不能同时被分给两个拥有者。当auto_ptr对象生命周期结束时,其析构函数会将auto_ptr对象拥有的动态内存自动释放。即使发生异常,通过异常的栈展开过程也能将动态内存释放。auto_ptr不支持new 数组。 2. auto_ptr需要包含的头文件? #include 3. 初始化auto_ptr对象的方法? 1) 构造函数 1] 将已存在的指向动态内存的普通指针作为参数来构造 int* p = new int(33); auto_ptr api(p); 2] 直接构造智能指针

auto_ptr< int > api( new int( 33 ) ); 2) 拷贝构造 利用已经存在的智能指针来构造新的智能指针 auto_ptr< string > pstr_auto( new string( "Brontosaurus" ) ); auto_ptr< string > pstr_auto2( pstr_auto ); //利用pstr_auto来构造pstr_auto2因为一块动态内存智能由一个智能指针独享,所以在拷贝构造或赋值时都会发生拥有权转移的过程。在此拷贝构造过程中,pstr_auto将失去对字符串内存的所有权,而pstr_auto2将其获得。对象销毁时,pstr_auto2负责内存的自动销毁。 3) 赋值 利用已经存在的智能指针来构造新的智能指针 auto_ptr< int > p1( new int( 1024 ) ); auto_ptr< int > p2( new int( 2048 ) ); p1 = p2; 在赋值之前,由p1 指向的对象被删除。赋值之后,p1 拥有int 型对象的所有权。该对象值为2048。 p2 不再被用来指向该对象。 4. 空的auto_ptr 需要初始化吗? 通常的指针在定义的时候若不指向任何对象,我们用Null给其赋值。对于智能指针,因为构造函数有默认值0,我们可以直接定义空的auto_ptr如下: auto_ptr< int > p_auto_int; //不指向任何对象 5. 防止两个auto_ptr对象拥有同一个对象(一块内存) 因为auto_ptr的所有权独有,所以下面的代码会造成混乱。 int* p = new int(0); auto_ptr ap1(p); auto_ptr ap2(p); 因为ap1与ap2都认为指针p是归它管的,在析构时都试图删除p, 两次删除同一个对象的行为在C++标准中是未定义的。所以我们必须防止这样使用auto_ptr。 6. 警惕智能指针作为参数! 1) 按值传递时,函数调用过程中在函数的作用域中会产生一个局部对象来接收传入的auto_ptr(拷贝构造),这样,传入的实参auto_ptr就失去了其对原对象的所有权,而该对象会在函数退出时被局部auto_ptr删除。如下例: void f(auto_ptr ap) {cout<<*ap;} auto_ptr ap1(new int(0));

ICE代码详解

服务器端代码:主要包括几个大的类。 Ice::Communicator类: Ice run time的主要进入点是由本地接口 Ice::Communicator来表示的。和在客户端一样,在你在服务器中做任何别的事情之前,你必须调用 Ice::initialize,对Ice run time进行初始化。Ice::initialize 返回一个智能指针,指向一个Ice::Communicator实例:int main(int argc, char * argv[]) { Ice::CommunicatorPtr ic = Ice::initialize(argc, argv); // ... } 在离开你的main函数之前,你必须调用Communicator::destroy。 destroy操作负责结束Ice run time。特别地,destroy会等待任何还在运行 的操作调用完成。此外,destroy还会确保任何还未完成的线程都得以汇合(joined),并收回一些操作系统资源,比如文件描述符和内存。决不要让你的main函数不先调用destroy就终止;这样做会导致不确定的行为。

Ice::Application类: #include class MyApplication : virtual public Ice::Application { public: virtual int run(int, char * []) { //主要是来实现该run 的方法。 // Server code here... return 0; } }; int main(int argc, char * argv[]) { MyApplication app; return app.main(argc, argv); } Ice::Service类:

(完整word版)Mstar理论及实践篇

理论篇 ############################################################################### sp TvManager::mTvManager; 强指针sp 智能指针 在Android的源代码中,经常会看到形如:sp、wp这样的类型定义,这其实是Android中的智能指针。智能指针是C++中的一个概念,通过基于引用计数的方法,解决对象的自动释放的问题。在C++编程中,有两个很让人头痛的问题:一是忘记释放动态申请的对象从而造成内存泄露;二是对象在一个地方释放后,又在别的地方被使用,从而引起内存访问错误。程序员往往需要花费很大精力进行精心设计,以避免这些问题的出现。在使用智能指针后,动态申请的内存将会被自动释放(有点类似Java的垃圾回收),不需要再使用delete来释放对象,也不需要考虑一个对象是否已经在其它地方被释放了,从而使程序编写工作减轻不少,而程序的稳定性大大提高。 Android的智能指针相关的源代码在下面两个文件中: frameworks/base/include/utils/RefBase.h frameworks/base/libs/utils/RefBase.cpp 涉及的类以及类之间的关系如下图所示: Android中定义了两种智能指针类型,一种是强指针sp(strong pointer),一种是弱指针(weak pointer)。其实成为强引用和弱引用更合适一些。强指针与一般意义的智能指针概念相同,通过引用计数来记录有多少使用者在使用一个对象,如果所有使用者都放弃了对该对象的引用,则该对象将被自动销毁。 弱指针也指向一个对象,但是弱指针仅仅记录该对象的地址,不能通过弱指针来访问该对象,也就是说不能通过弱智真来调用对象的成员函数或访问对象的成员变量。要想访问弱指针所指向的对象,需首先将弱指针升级为强指针(通过wp类所提供的promote()方法)。弱指针所指向的对象是有可能在其它地方被销毁的,如果对象已经被销毁,wp的promote()方法将返回空指针,这样就能避免出现地址访问错的情况。 是不是很神奇?弱指针是怎么做到这一点的呢?其实说穿了一点也不复杂,原因就在于每一个可以被智能指针引用的对象都同时被附加了另外一个weakref_impl类型的对象,这

MFC实现SQL数据库ADO连接

VC MFC实现SQL数据库ADO连接(完整版)关于vc6.0中实现ADO SQL数据库连接的文章网上虽然很多,但大多写的很繁琐,对于我们这样的菜鸟来说,还是很希望有一篇简单化的文章的。希望跟我一样的菜鸟们学得开心! 源代码文件链接: 概述: 要在一个vc工程中实现数据库的连接,最好的方式是在新建一个用于连接数据库的类比如ADOConn,需要连接数据库的时候将这个类实例化就可以了。 操作:新建一个ADOConn的对象,比如ADOConn ac;。然后再引用些对象就可以实现相应的操作了。 实践过程: (一)目的:封装一个自己的类。 在vc6.0中新建一个基于对话框的mfc工程,然后点击菜单栏->插入->类(mfc类)。 然后在“类的类型”中选择Generic Class,名称为ADOConn。 此后会在vc左边视窗的“Source Files”中多出一个ADOConn.cpp的文件,在"Header Files"中多出一个“ADOCon.h”的文件。 如果是用VS2013来创建工程的情况: VS2013中添加类:

右击myMFC(新建的项目)——添加——类——MFC类。 (二)打开ADOConn.h(即编辑ADOConn类的头文件) (1)在第一行加入(用于vc支持ado连接) 这句话意味使用msado15.dll动态连接库文件,里面就有ADO. 如果存在问题:用VS2010的C++导入ADO导入不了,提示无法打开源文件msado15.tlh”的问题。 解决办法很简单: 在生成菜单--- 重新生成 --- 即可。 原因是: 当编译器遇到#import语句时,它会为引用组件类型库中的接口生成包装类,#import语句实际上相当于执行了API涵LoadTypeLib()。 #import语句会在工程可执行程序输出目录中产生两个文件,分别为*.tlh(类型库头文件)及*.tli(类型库实现文件),它们分别为每一个接口产生智能指针,并为各种接口方法、枚举类型,CLSID 等进行声明,创建一系列包装方法。在没有经过编译器编译之前,文件还没有生成,所以,会出现错误提示。 (2)在class ADOConn类体中添加如下代码

C++智能指针

【C++】智能指针类和OpenCV的Ptr模板类 2015-03-29 21:18 智能指针类 引用计数 智能指针(smart pointer)的一种通用实现技术是使用引用计数(reference count)。智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象的指针指向同一对象。引用计数为0时,删除对象。 其基本使用规则是: 每次创建类的新对象时,初始化指针并将引用计数置为1。当对象作为另一对象的副本而创建时,复制构造函数复制指针并增加与之相应的引用计数的值。对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数的值(如果引用计数减至0,则删除对象),并增加右操作数所指对象的引用计数的值。最后,调用析构函数时,析构函数减少引用计数的值,如果计数减至0,则删除基础对象。 实现引用计数有两种经典策略:一是引入辅助类(包含引用计数型),二是使用句柄类(分离引用计数型)。 策略1:引用计数类 这个类的所有成员均为private。我们不希望用户使用U_Ptr 类,所以它没有任何public 成员。将HasPtr 类设置为友元,使其成员可以访问U_Ptr 的成员。 U_Ptr 类保存指针和使用计数,每个HasPtr 对象将指向一个U_Ptr 对象,使用计数将跟踪指向每个 U_Ptr 对象的HasPtr 对象的数目。U_Ptr 定义的仅有函数是构造函数和析构函数,构造函数复制指针,而析构函数删除它。构造函数还将使用计数置为1,表示一个HasPtr 对象指向这个U_Ptr 对象。 class U_Ptr { friend class HasPtr; int *ip; int use; U_Ptr(int *p):ip(p){} ~U_Ptr() { delete ip; } }; class HasPtr { public: HasPtr(int *p, int i):_ptr(new U_Ptr(p)),_val(i) {} HasPtr(const HasPtr& obj):_ptr(obj._ptr),_val(obj._val) { ++_ptr->use; } HasPtr& operator=(const HasPtr&); ~HasPtr() {

智能指针

在你的代码中使用Boost智能指针 Smart Pointers to boost your code(By peterchen) 翻译 masterlee Download source files - 45.3kb 正文 智能指针能够使C++的开发简单化,主要是它能够像其它限制性语言(如C#、VB)自动管理内存的释放,而且能够做更多的事情。 1、什么是智能指针 智能指针是一种像指针的C++对象,但它能够在对象不使用的时候自己销毁掉。 我们知道在C++中的对象不再使用是很难定义的,因此C++中的资源管理是很复杂的。各种智能指针能够操作不同的情况。当然,智能指针能够在任务结束的时候删除对象,除了在程序之外。 许多库都提供了智能指针的操作,但都有自己的优点和缺点。Boost库是一个高质量的开源的C++模板库,很多人都考虑将其加入下一个C++标准库的版本中。 下面让我们看一个简单的例子: 2、首先介绍:boost::scoped_ptr scoped_ptr 是 Boost 提供的一个简单的智能指针,它能够保证在离开作用域后对象被释放。 例子说明:本例子使用了一个帮助我们理解的类: CSample, 在类的构造函数、赋值函数、析构函数中都加入了打印调试语句。因此在程序执行的每一步都会打印调试信息。在例子的目录里已经包含了程序中需要的Boost库的部分内容,不需要下载其它内容(查看Boost的安装指南)。

使用普通普通指针的时候,我们必须记住在函数退出的时候要释放在这个函数内创建的对象。当我们使用例外的时候处理指针是特别烦人的事情(容易忘记销毁它)。使用scoped_ptr 指针就能够在函数结束的时候自动销毁它,但对于函数外创建的指针就无能为力了。 优点:对于在复杂的函数种,使用scoped_ptr 指针能够帮助我们处理那些容易忘记释放的对象。也因此在调试模式下如果使用了空指针,就会出现一个断言。 3、引用指针计数器 引用指针计数器记录有多少个引用指针指向同一个对象,如果最后一个引用指针被销毁的时候,那么就销毁对象本身。 shared_ptr 就是Boost中普通的引用指针计数器,它表示可以有多个指针指向同一个对象,看下面的例子: void Sample2_Shared() { // (A)创建Csample类的一个实例和一个引用。 boost::shared_ptr mySample(new CSample); printf("The Sample now has %i references\n", https://www.doczj.com/doc/ce5858474.html,e_count()); // The Sample now has 1 references // (B)付第二个指针给它。 boost::shared_ptr mySample2 = mySample; // 现在是两个引用指针。 printf("The Sample now has %i references\n", https://www.doczj.com/doc/ce5858474.html,e_count()); // (C) 设置第一个指针为空。 mySample.reset(); printf("The Sample now has %i references\n", https://www.doczj.com/doc/ce5858474.html,e_count()); // 一个引 用 // 当mySample2离开作用域的时候,对象只有一个引用的时候自动被删除。 } 在(A)中在堆栈重创建了CSample类的一个实例,并且分配了一个shared_ptr指针。对象mySample入下图所示: 然后我们分配了第二个指针mySample2,现在有两个指针访问同一个数据。 我们重置第一个指针(将mySample设置为空),程序中仍然有一个Csample实例,mySample2有一个引用指针。 只要当最有一个引用指针mySample2退出了它的作用域之外,Csample这个实例才被销毁。 当然,并不仅限于单个Csample这个实例,或者是两个指针,一个函数,下面是用shared_ptr的实例: 用作容器中。

ADO智能指针使用详解

ADO智能指针使用详解 一、ADO接口——Connection对象(连接对象)——对应智能指针为_ConnectionPtr 在使用ADO进行操作之前,必须使用AfxOleInit()函数来进行初始化。 使用BeginTrans、CommitTrans和RollbackTrans方法可以启动、提交和回滚一个处理事务。 通过操作the Errors 集合可以获取和处理错误信息,操作CommandTimeout属性可以设置连接的溢出时间,操作ConnectionString属性可以设置连接的字符串,操作Mode属性可以设置连接的模式,操作Provider属性可以指定OLE DB提供者。 (1)Open()方法:用于打开一个库连接 _ConnectionPtr智能指针的用法: ①首先定义一个Connection类型的指针,然后调用CreateInstance()来创建一个连接对象的实例,再调用Open()函数建立与数据源的连接。 ②在建立连接对象后,可以使用连接对象的Execute()函数来执行SQL命令。 _ConnectionPtr智能指针Open()方法的原型:Open(_bstr_t ConnectionString,_bstr_t UserID,_bstr_t Password,long Options) ①ConnectionString为连接字串,UserID是用户名,Password是登陆密码 ②Options是连接选项,可以是如下几个常量: 1> adModeUnknown 缺省,当前的许可权未设置 2> adModeRead 只读 3> adModeWrite 只写 4> adModeReadWrite 可以读写 5> adModeShareDenyRead 阻止其它Connection对象以读权限打开连接 6> adModeShareDenyWrite 阻止其它Connection对象以写权限打开连接 7> adModeShareExclusive 阻止其它Connection对象打开连接 8> adModeShareDenyNone 阻止其它程序或对象以任何权限建立连接 (2)Execute()方法:用于执行SQL语句 函数原型:_RecordsetPtr Connection::Execute(_bstr_t CommandText,VARIANT* RecordsAffected,long Options) 参数: ①CommandText是命令字串,通常是SQL命令, ②RecordsAffected是操作完成后所影响的行数 ③Options表示CommandText中内容的类型,可以取下列值之一: 1> adCmdText 表明CommandText是文本命令 2>adCmdTable 表明CommandText是一个表名

软件类笔试试题

什么是编译? 编译器是将一种语言翻译为另一种语言的计算机程序。编译器将源程序(source language)编写的程序作为输入,而产生用目标语言(target language )编写的等价程序。通常地,源程序为高级语言(high-level language ),如C或C + + ,而目标语言则是目标机器的目标代码(object code,有时也称作机器代码(machine code )),也就是写在计算机机器指令中的用于运行的代码。这一过程可以表示为:源程序→编译器→目标程序 什么是java? Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由Sun Microsystems 公司于1995年5月推出的Java程序设计语言和Java平台(即JavaSE, JavaEE, JavaME)的总称。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于个人PC、数据中心、游戏控制台、科学超级计算机、移动电话和互联网,同时拥有全球最大的开发者专业社群。在全球云计算和移动互联网的产业环境下,Java更具备了显著优势和广阔前景。 什么是c语言 C语言是一种计算机程序设计语言。它既具有高级语言的特点,又具有汇编语言的特点。它由美国贝尔研究所的D.M.Ritchie于1972年推出。1978后,C语言已先后被移植到大、中、小及微型机上。它可以作为工作系统设计语言,编写系统应用程序,也可以作为应用程序设计语言,编写不依赖计算机硬件的应用程序。它的应用范围广泛,具备很强的数据处理能力,不仅仅是在软件开发上,而且各类科研都需要用到C语言,适于编写系统软件,三维,二维图形和动画。具体应用比如单片机以及嵌入式系统开发。 什么是c++语言 l l 对于要解决实际问题的程序员而言,C++使程序设计变得更有乐趣; l l C++是一门通用目的的程序设计语言,它: ——是一个更好的C; ——支持数据抽象; ——支持面向对象程序设计; ——支持范型程序设计。 对范型程序设计的支持在C++设计的后期才被作为一个明确、独立的目标来实现。而在C++演化过程的大部分时间里,我一直把范型程序设计以及支持它的语言特性划归在“数据抽象”的大标题之下。

C++ 智能指针详解

C++ 智能指针详解 一、简介 由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete。程序员忘记 delete,流程太复杂,最终导致没有 delete,异常导致程序过早退出,没有执行 delete 的情况并不罕见。 用智能指针便可以有效缓解这类问题,本文主要讲解参见的智能指针的用法。包括:std::auto_ptr、boost::scoped_ptr、boost::shared_ptr、 boost::scoped_array、boost::shared_array、boost::weak_ptr、 boost::intrusive_ptr。你可能会想,如此多的智能指针就为了解决new、delete 匹配问题,真的有必要吗?看完这篇文章后,我想你心里自然会有答案。 下面就按照顺序讲解如上 7 种智能指针(smart_ptr)。 二、具体使用 1、总括 对于编译器来说,智能指针实际上是一个栈对象,并非指针类型,在栈对象生命期即将结束时,智能指针通过析构函数释放有它管理的堆内存。所有智能指针都重载了“operator->”操作符,直接返回对象的引用,用以操作对象。访问智能指针原来的方法则使用“.”操作符。 访问智能指针包含的裸指针则可以用 get() 函数。由于智能指针是一个对象,所以if (my_smart_object)永远为真,要判断智能指针的裸指针是否为空,需要这样判断:if (my_smart_object.get())。 智能指针包含了 reset() 方法,如果不传递参数(或者传递 NULL),则智能指针会释放当前管理的内存。如果传递一个对象,则智能指针会释放当前对象,来管理新传入的对象。 我们编写一个测试类来辅助分析: class Simple { public: Simple(int param = 0) { number = param; std::cout << "Simple: " << number << std::endl; } ~Simple() { std::cout << "~Simple: " << number << std::endl;

android智能指针(wp、sp)学习总结

智能指针:强指针sp,弱指针wp,轻量级指针LightRefBase。 相关文件:RefBase.h,RefBase.cpp,StrongPointer.h(注:参考代码android 4.2.2)。RefBase.h:定义了RefBase类定义,wp模板类定义和实现,以及LightRefBase类定义。RefBase.cpp:定义了RefBase类实现以及RefBase的嵌套类weakref_type的实现。StrongPointer.h:定义了sp模板类定义和实现。 RefBase类主要方法如下: void RefBase::incStrong(const void* id) const { weakref_impl* const refs = mRefs; refs->incWeak(id); // 增加一次弱引用计数 refs->addStrongRef(id); // 空函数 // 原子操作,增加一次强引用计数,返回的是refs->mStrong执行加1操作之前的值const int32_t c = android_atomic_inc(&refs->mStrong); ALOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs); // 第一次执行,c的值为INITIAL_STRONG_V ALUE if (c != INITIAL_STRONG_V ALUE) {//从第二次开始执行后,此条件都成立,直接返回return; } // 执行操作,refs->mStrong + (-INITIAL_STRONG_V ALUE),第一次执行后强引用计数refs->mStrong值变为1 android_atomic_add(-INITIAL_STRONG_V ALUE, &refs->mStrong); refs->mBase->onFirstRef(); //第一次执行会调用该方法,子类可以覆盖该方法。 } void RefBase::decStrong(const void* id) const { weakref_impl* const refs = mRefs; refs->removeStrongRef(id); // 空函数 // 原子操作,强引用计数减1,返回的是执行减1操作之前的值 const int32_t c = android_atomic_dec(&refs->mStrong); ALOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs); if (c == 1) { refs->mBase->onLastStrongRef(id); // 子类可覆盖该方法 // mFlags值缺省为0 if ((refs->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) { delete this; } } refs->decWeak(id); // 弱引用计数减1 } void RefBase::forceIncStrong(const void* id) const {

C++boost库总结

第1章Boost程序库总论 1. 使用Boost,将大大增强C++的功能和表现力 第2章时间与日期 1. timer提供毫秒级的计时精度,内部是通过std::clock 取时间的 2. progress_timer 自动打印某生命周期的执行时间 3. 原则上程序库的代码是不应该被用户修改的 4. progress_display 可以在控制台上显示程序的执行进度 5. date_time 库能很好的表示日期时间概念,并能和C的时间结构tm进行友好互转 6. date类提供年月日和星期几的概念。data可通过from_string 或 from_un delimited_stri ng 从字符串解析而来,可通过to_simple_stri ng 、 to_iso_string 、to_extended_iso_string 转换为字符串。(精度至U天的DateTime ) 7. day_clock是精度到天的时钟 8. date_duration 表示的是天精度的时间间隔概念,别名为days,另外还有years、 mon ths 、weeks 9. date_period 表示两个date之间的日期区间(精度到天的TimeSpan ) 10. date_iterator 、week_iterator 、month」terator 和year_iterator 是时间的迭 代器 11. boost:: greorian ::gregorian_calendar 中有实用静态方法:is_leap_year、 en d_of_m on th_day 12. time_duration 表示微妙或纳秒级的时间概念,几个实用子类:hours、minutes、 seconds 、millisec/milliseconds 、microsec/microseconds 、 nano sec/ nanno sec onds

VC++中操作XML(MFC、SDK)

VC++中操作XML(MFC、SDK) XML在Win32程序方面应该没有在Web方面应用得多,很多Win32程序也只是用XML来存存配置信息而已,而且没有足够的好处的话还不如用ini。VC++里操作XML有两个库可以用:MSXML和XmlLite。MSXML又细分了两种接口:DOM和SAX2。XP没自带有XmlLite,只自带有2.x、3.x版的MSXML,不支持SAX2(需要MSXML 4.0以上),所以优先使用DOM。 DOM是以COM形式提供的,VC++里调用DOM可以分3种方法: 1、MFC里用CComPtr调用 2、SDK里直接调用DOM接口 3、SDK里用智能指针调用 这3种方法本质上是一样的,区别只不过在于需要编码的多少而已,用CComPtr可以极大的简化代码,下面是几个例子。 例子stocks.xml: text1 childtext1 这个例子应该包含了XML最常见的特征了吧? MFC MFC里可以直接使用DOM,不需要手动添加额外的头文件,只需要在CWinApp::InitInstance()里调用CoInitialize(NULL)初始化COM,在CWinApp::ExitInstance里调用CoUninitialize()释放COM就行了。//读取XML CComPtr spDoc;//DOM spDoc.CoCreateInstance(CLSID_DOMDocument); VARIANT_BOOL vb; spDoc->load(CComVariant(OLESTR("stocks.xml")), &vb);//加载XML文件 CComPtr spRootEle; spDoc->get_documentElement(&spRootEle);//根节点 CComPtr spNodeList; spRootEle->get_childNodes(&spNodeList);//子节点列表 long nLen; spNodeList->get_length(&nLen);//子节点数 for(long i =0; i != nLen;++i)//遍历子节点 { CComPtr spNode; spNodeList->get_item(i, &spNode); ProcessNode(spNode);//节点处理函数 }

boost智能指针的使用

1. 定义 一个智能指针就是一个C++的对象,这对象的行为像一个指针,但是它却可以在其不需要的时候自动删除。注意这个“其不需要的时候”,这可不是一个精确的定义。这个不需要的时候可以指好多方面:局部变量退出函数作用域、类的对象被析构……。所以boost定义了多个不同的智能指针来管理不同的场景。 2. Boost::scoped_ptr scoped_ptr 是boost中最简单的智能指针。scoped_ptr的目的也是很简单,当一个指针离开其作用域时候,释放相关资源。特别注意的一定就是scoped_ptr 不能共享指针的所有权也不能转移所有权。也就是说这个内存地址就只能给的声明的变量用,不能给其他使用。 下面是scoped_ptr的几个特点: scoped_ptr的效率和空间的消耗内置的指针差不多。 scoped_ptr不能用在标准库的容器上。(用shared_ptr代替) scoped_ptr 不能指向一块能够动态增长的内存区域(用scoped_array代替) 1.class test 2.{ 3.public: 4. void print() 5. {

6. cout << "test print now" < x(new test); 12. x->print(); 13. return 0; 14.} 3.Boost::shared_ptr shared_ptr 具有如下几个特点: 1.在内部维护一个引用计数器,当有一个指针指向这块内存区域是引用计数+1,反之-1,如果没有任何指针指向这块区域,引用计数器为0,释放内存区域。 2.可以共享和转移所有权。 3.可以被标准库的容器所使用 4.不能指向一块动态增长的内存(用share_array代替) 我们可以看下如下例子: 1.int _tmain(int argc, _TCHAR* argv[]) 2.{ 3.boost::shared_ptr ptr_1(new test); 4. ptr_1->print();//引用计数为1 5. boost::shared_ptr ptr_2 = ptr_1; 6. ptr_2->print();//引用计数为2 7. ptr_1->print();// 引用计数还是为2 8. return 0;

CATIA二次开发详解点汇总

1.Framework 2.Module(空的,用来放workbenchs,components,workbench要把原来的module清掉,components不用,它是直接在上面加的东西) 3.Framework:public 用来放盛workbench的module头文件 Private:这个是加进来workbench怎么继承上面的一个类 还一个是生成一个workebench的出去文件 3.IdentityCard 用来放外部或系统的API所属的外部框架定义 4.mk文件时定义外部或系统的API所属的外部模块定义 查看dico 外部框架外部模块在相应的文件定义是关键 5.这里有三个文件 CA TNIs可以定义此Workbench以及其工具条、菜单的所有名字(Title),定义格式为:TestWb.Title=”test”; CA TRsc可以定义此Workbench的图标(Icons)和其放置路径(Category)(这里放模块) MyWorkbench.Icon.NormalPnl="Clouds"; MyWorkbench.Icon.NormalCtx="Clouds"; MyWorkbench.Icon.NormalRep="Clouds"; MyAddin.CATNls中添加 MybenchTlb.Title="月亮"; MyCmdHeader.CA TRsc中添加 MyCmdHeader.point.Icon.Normal="mycmd"; 另一个CA TNIs文件是实现workbench的命令头文件 6..dico文件定义的是链接库 还一个是工厂定义 新建一个workbench的时候,首先要以workbench名声明一个工厂 然后CATApplicationFrame框与工厂进行库连接 给新建的workbench 与它下面的配置文件接口进行库连接 7.在Module中的trsc文件是A TIE is the object that links the interface and the implementation TIE以trsc的形式存在 在这个workbench所在的模块里面有src里面是本模块的CPP文件集合,local interface里面是本模块的.h文件集合,包括 ①上面提到的trsc文件,用来链接接口和现实的对象的的,主要是两组继承,工厂的继 承和addin的继承2 ②还有从基工厂类上继承一个wokbench工厂所需要的cpp和.h文件。还一个是创建一个 新工厂1 ,1 || 1 ,1 ③还有将执行的命令用MacDefineHeader宏定义当前的workbench命令,也有.h文件和 CPP文件1,1 ④实现现实的对象需要header.h workshop.h 还有就是就是从最初基类 CA TBaseUnknown继承下来的派生类1,3 ⑤还有一个是interface此接口是定义addin接口文件,用来继承库中的addin 1,1 8.setting CATIA 可以启动看到workbench了 9.添加工具条

OPC客户端的实现

1引言 OPC(OLE for Process Control)是一个工业标准,他是许多世界领先的自动化和软、硬件公司与微软公司合作的结晶。管理该标准的组织是OPC基金会。该基金会的会员单位在世界范围内超过150个,包括了世界上几乎全部的控制系统、仪器仪表和过程控制系统的主要供应商。OPC 技术建立了一组符合工业控制要求的接口规范,将现场信号按照统一的标准与SCADA、HMI等软件无缝连接起来,同时将硬件和应用软件有效地分离开。只要硬件开发商提供带有OPC接口的服务器,任何支持OPC接口的客户程序均可采用统一的方式对不同硬件厂商的设备进行存取,无须重复开发驱动程序。如果希望将数据引入数据库进行统计分析,就要进行客户端开发。 2客户程序的设计方法与比较 客户程序的设计主要是指客户程序中OPC接口部分的设计。客户程序本身可以完成很多复杂的数据处理与显示功能,但需要通过OPC接口部分访问OPC服务器,对现场数据进行存取。 开发OPC、Data、Access、Client之前,要弄清服务器的大体情况,比如需要访问的服务器是否提供自动化接口、服务器的OPC的版本等,到目前为止,OPC有1.0和2.0两个版本,两个版本的接口定义不同,2.0版是对1.0的改进,但不兼容。 OPC客户端的主要任务: ①创建服务器对象。 ②建立与服务器的连接。 ③浏览OPC服务器的功能。客户程序需要创建OPC基金会提供的OPC服务器浏览器对象(OPCServerList)再通过该对象的IOPCServerList接口获得OPC服务器名称的列表;可以通过枚举注册表中包含“OPC”子键的程序名来浏览符合OPC数据存取规范的服务器,但效率较低。 ④通过OPC接口读写数据。 ⑤断开连接。

C 箴言将new出来的对象存入智能指针解析

C++箴言:将new出来的对象存入智能指针 不要忘记使用对象管理资源的至理名言,processWidget 为处理动态分配的Widget 使用了一个智能指针。 假设我们有一个函数取得我们的处理优先级,而第二个函数根据优先级针 Widget 使用了一个智能指针(在此,是一个 tr1::shared_ptr)。 个裸指针(raw pointer)应该是显式的,所以不能从一个由 "new Widget" 返回的裸指针隐式转型到 processWidget 所需要的 tr1::shared_ptr.下面的代 还是可能泄漏资源。下面就来说明这是如何发生的。 在编译器能生成一个对 processWidget 的调用之前,它们必须传递实际参数来计算形式参数的值。第二个实际参数不过是对函数 priority 的调用,但是第一个实际参数("std::tr1::shared_ptr(new Widget)"),由两部分组成: ·表达式 "new Widget" 的执行。 ·一个对 tr1::shared_ptr 的构造函数的调用。 在 processWidget 能被调用之前,编译器必须为这三件事情生成代码:·调用 priority。 ·执行 "new Widget"。 ·调用 tr1::shared_ptr 的构造函数。 C++编译器允许在一个相当大的范围内决定这三件事被完成的顺序。(这里与Java和C#等语言的处理方式不同,那些语言里函数参数总是按照一个精确的顺序被计算。)"new Widget" 表达式一定在 tr1::shared_ptr 的构造函数能被调用之前执行,因为这个表达式的结果要作为一个参数传递给 tr1::shared_ptr 的构造函数,但是 priority 的调用可以被第一个,第二个或第三个执行。如果编译器选择第二个执行它(大概这样能使它们生成更有效率的代码),我们最终得到这样一个操作顺序: ·执行 "new Widget"。 ·调用 priority。 ·调用 tr1::shared_ptr 的构造函数。 但是请考虑,如果对 priority 的调用引发一个异常将发生什么。在这种情况下,从 "new Widget" 返回的指针被丢失,因为它没有被存入我们期望能阻止

auto_ptr到底能不能作为容器的元素

auto_ptr到底能不能作为容器的元素? 【摘要】对C++语言本身来说,它并不在乎用户把什么类型的对象作为STL容器的元素,因为模板类型参数在理论上可以为任何类型。比如说STL容器仅支持“值”语义而不支持“引用(&)”语义,并非因为模板类型参数不能为引用,而是因为如果容器元素为引用类型,就会出现“引用的引用”、“引用的指针”等C++语言不支持的语法和语义。智能指针是一种模拟原始指针行为的对象,因此理论上也可以作为容器的元素,就象原始指针可以作为容器元素一样。但是智能指针毕竟是一种特殊的对象,它们在原始指针共享实值对象的基础能力上增加了自动销毁实值对象的能力,如果将它作为容器的元素,可能导致容器之间共享元素对象实值,这不仅不符合STL容器的概念和“值”语义,也会存在安全隐患,同时也会存在许多应用上的限制,特别是象STL中的auto_ptr这样的智能指针。本文深入地阐述了auto_ptr这种较简单的智能指针“可以”或者“不可以”作为容器元素的根本原因,以及它作为容器元素会存在的限制和带来的问题,最后说明auto_ptr存在的真正意义、正确的使用方法以及它的替代品——带有引用计数能力的智能指针,当容器之间需要共享元素对象时,或者程序中存在大量的指针传递而担心资源泄漏时,这样的智能指针就特别有用。 【关键字】auto_ptr 容器智能指针 一、引言 Scott Meyers在《More Effective C++》[3]一书中对智能指针及其相关问题(构造、析构、复制、提领、测试以及类型转换等)作了深入的分析,其中也提到“STL的auto_ptr这种在复制时会把对实值对象的拥有权转交出去的智能指针不宜作为STL容器的元素”,而且在他的《Effective STL》[4]Item 8中明确指出了这一点。Nicolai M.Josuttis的《The C++ Standard Library》[5]中有一节专门针对auto_ptr的阐述也指出“auto_ptr不满足STL标准容器对元素的最基本要求”。但是他们都是从容器的需求、语义以及应用的安全性来阐述,而没有从语言的静态类型安全性和auto_ptr的实现方案角度深入地分析其原因,因此有些读者看了之后可能仍然不明就里:它是如何不满足容器需求的?它是如何违反C++的静态类型安全性从而避免误用的? 我们知道,可以作为STL容器的元素的数据类型一般来说需要满足下列条件: (1)可默认构造的(Default Constructible),也即具有public的default constructor,不论是用户显式定义的还是编译器自动合成的。但是用户定义的带参数的constructor(包括copy constructor)会抑制编译器合成default constructor。实际上并非任何情况下任何一种容器都强制要求其元素类型满足这一要求,特别是关联式容器,因为只有序列式容器的某些成员函数才可能明确地或隐含地使用元素类型的默认构造函数,如果你不使用这样的成员函数,编译器就不需要元素类型的默认构造函数; (2)可拷贝构造(Copy Constructible)和拷贝赋值(Copy Assignable)的,即具有public的copy constructor和copy assignment operator,不论是编译器自动合成的还是用户显式定义的。其它版本的operator=()重载并不会抑制编译器合成copy assignment operator,如果你没有显式定义它的话。这个条件可归结为:元素必须是可拷贝的(Copyable),但实际上拷贝赋值的要求也不是强制的,原

相关主题
文本预览
相关文档 最新文档