当前位置:文档之家› 运用CAR智能指针实现Callback机制

运用CAR智能指针实现Callback机制

运用CAR智能指针实现Callback机制
运用CAR智能指针实现Callback机制

收稿日期:2007-05-31

基金项目:国家“863”计划资助项目(2001AA113400)

作者简介:叶 蓉(1980-),女,江苏南京人,硕士研究生,研究方向为嵌入式操作系统、系统软件支撑技术;陈 榕,教授,博士生导师,研究方向为嵌入式系统、构件技术。

运用CAR 智能指针实现C allb ack 机制

叶 蓉1,2,陈 榕1

(1.同济大学基础软件工程中心,上海200092;

2.上海第二工业大学,上海201209)

摘 要:“和欣”操作系统是基于CAR 构件技术、支持构件化应用的嵌入式操作系统。一般的构件,客户与构件之间的通信过程是单向的,客户创建构件对象,然后客户调用对象所提供的接口函数。在这样的通讯过程中,客户总是主动的,而构件对象则处于被动状态。对于一个全面的交互过程来说,这样的单向通信往往不能满足实际的需要,构件对象也要主动与客户进行通信,构件也提供回调接口。和欣系统中的Callback 机制有助于实现二进制构件拼装;并允许构件异地运行,可极大地提高构件的运行效率,但其本身实施过程很复杂。提出在“和欣”操作系统中,实现CAR 智能指针来简化用户实现Callback 机制的过程。

关键词:CAR ;CAR 智能指针;Callback 机制

中图分类号:TP311 文献标识码:A 文章编号:1673-629X (2008)02-0009-04

Using CAR Smart Pointer to R ealize C allback Mechanism

YE Rong 1,2,CHEN Rong 1

(1.System S oftware Engineering Centre of Tongji University ,Shanghai 200092,China ;

2.Shanghai Second Polytechnic University ,Shanghai 201209,China )

Abstract :Elastos operating system ,which can sustain component applications ,is based on component assembly runtime https://www.doczj.com/doc/9a16747004.html, 2munication process between normal component and client is one -way oriented ,client builds component object ,and then calls interface provided by the object.In this communication process ,the client is always active ,and component object is in a passive state.For a com 2prehensive interactive process ,such one -way communication often cannot meet the actual needs ,component object also need take the initiative to communicate with client ,as well as to provide call back interface.Elastos Callback mechanism is helpful for binary compo 2nents ’integration and it allows components running in different context ,which largely improves the CAR component running efficiency.However the normal Callback implementation is too much complicated during execution.Depicts how to use CAR smart pointer to sim 2plize the application procedure of Callback mechanism.

K ey w ords :component assembly runtime ;CAR smart pointer ;Callback mechanism

0 引 言

基于构件的软件工程是实现高生产率、低维护费用和高可靠软件产品的关键技术。构件的使用方式类似于“客户/服务器”模型,其中构件充当服务器的角色。

一般的构件,客户与构件之间的通信过程是单向的,客户创建构件对象,然后客户调用对象所提供的接口函数。在这样的通讯过程中,客户总是主动的,而构

件对象则处于被动状态。对于一个全面的构件交互过程来说,这样的单向通信往往不能满足实际的需要,有时候构件对象也要主动与客户进行通信,因此,与普通接口(interface ,也称为入接口)相对应,构件也可以提供回调接口(icallback ,也称为出接口),对象通过回调接口与客户进行通信。Callback 机制有助于实现二进制构件拼装;并允许构件异地运行。极大地提高了构件的运行效率,但Callback 机制实施过程很复杂,因此采用类智能指针包装其交互过程来简化用户使用的复杂性。

文中提出在CAR 构件技术中运用智能指针对客户端进行简化,以方便用户使用CAR 构件。用户可以通过宏定义选择直接通过接口指针进行操作,亦可以选择通过智能指针完成对接口的使用。CAR 的智能

第18卷 第2期2008年2月 计算机技术与发展COMPU TER TECHNOLO GY AND DEV ELOPMEN T

Vol.18 No.2Feb. 2008

指针可以向用户屏蔽了对构件生命周期的管理,用户使用智能指针,无需再去考虑繁琐复杂的AddRef 、Re 2

lease 的调用,简化了编程的步骤,降低编程难度,同时

确保客户能正确地控制构件的生命周期,提高了用户应用程序的安全性,降低了资源泄漏的可能;通过智能指针能够检查接口的类型安全性,消除潜在的错误。

1 “和欣”操作系统和CAR 构件编程环境

1.1 “和欣”操作系统

“和欣”[1]操作系统是863计划的“基于中间件技

术的因特网嵌入式操作系统及跨操作系统中间件运行平台”的重要成果,是一个基于构件的灵活内核现代操作系统。“和欣”操作系统与宏内核或微内核操作系统的最大区别就是其将微内核模型与基于构件技术的充分结合,形成了“和欣”操作系统的灵活内核架构模型。

1.2 CAR 构件程序集运行时

CAR (Component Assembly Runtime )是国内拥有

自主知识产权的先进构件系统。CAR 构件技术定义了一套网络编程时代的构件编程模型和编程规范,它规定了一组构件间相互调用的标准,使得二进制构件能够自描述,能够在运行时动态链接。CAR 构件技术继承了COM [2,3]的二进制封装思想,面向接口编程。在逐步融合.Net 、Java 技术思想之后,形成独有的二进制构件程序模型。CAR 构件技术采用C ++编程,使用和欣SD K 提供的工具直接生成运行于和欣构件运行平台的二进制代码。因此CAR 构件机制使得程序员能够充分运用自己熟悉的编程语言知识和开发经验,很容易掌握面向构件、中间件编程的技术。

2 用智能指针实现CAR 回调机制

2.1 回调机制

构件模块之间总是存在着一定的接口,从调用方式上,可以分为三类:同步调用、回调和异步调用。同步调用是一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用;回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口;异步调用是一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件

时,会主动通知被调用方(即调用被调用方的接口)。回调和异步调用的关系非常紧密,通常使用回调来实现异步消息的注册,通过异步调用来实现消息的通知。同步调用是三者当中最简单的,而回调又常常是异步调用的基础。

具体来说,回调如图1所示,就是模块A 调用模块B ,而模块B 中要调用模块A 中的函数C 的代码,其中函数C 就是回调函数

;

图1 回调机制的实现

客户端(模块A 地址空间)首先通过同步方式调用服务端(模块B 地址空间)的注册接口来注册回调接口,服务端收到该请求以后,就会保留该接口引用,如果发生某种事件需要向客户端通知的时候就通过该引用调用客户方的回调函数,以便对方及时处理。

在CAR 的回调机制中,有一种接收器(sink )对象,接收器对象相当于一个客户端回调函数的容器,在客户端的地址空间里,负责与可连接对象进行通信。只要有可连接对象存在,那么在客户端肯定要有接收器的存在。多个回调接口可对应一个接收器对象,这样可以减少通信花费的开销。当接收器与可连接对象建立连接后,客户程序可将自己实现的事件处理函数(回调函数)向接收器进行注册,

而不是向可连接对象进行

图2 CAR 回调机制具体实现

?

01? 计算机技术与发展 第18卷

注册,又一次减少了通信开销。接收器会自动把在它里面注册的函数的回调接口指针告诉构件对象,构件对象在条件成熟时激发事件,如果客户注册了自己的回调接口方法,那么就会被调用,否则就调用接收器默认实现的回调接口方法。其过程如图2所示。

在编写构件程序时,用户需定义何时激发事件,在编写客户端程序时,用户需在适当的时候注册事件处理函数。其它的工作,如接收器对象的实现、接收器与可连接对象建立通信的具体过程、事件的分发回调过程等都由CAR 实现。

2.2 未采用CAR 智能指针实现回调(C allback)机制

未使用CAR 智能指针的回调(Callback )过程如图

3所示

图3 未使用CAR 智能指针的Callback 机制实现从图中可以看出,Callback 机制实施过程比较复杂,用户需自行创建可连接对象以及接收器,并在接收器中注册对应的回调事件,回调事件触发后,用户还需要向接收器对象注销对应的回调事件,并断开与可连接对象的连接。这一系列过程本身比较复杂,不易于用户的使用。由此,提出采用CAR 智能指针为用户封装Callback 机制的细节,方便用户的使用。

2.3 CAR 智能指针实现回调(C allback)机制

通过CAR 智能指针简化用户实现Callback 机制的过程如图4所示。

对比图3和图4可以看出,CAR 构件技术提供智能指针对客户端进行简化,以方便用户使用CAR 构

件。

图4 使用CAR 智能指针的Callback 机制实现

CAR 的智能指针向用户屏蔽了对构件回调事件

的处理,用户无需再去考虑繁琐复杂的初始化及注册

过程,简化了编程的步骤,降低编程难度,同时CAR 的智能指针确保客户能正确地控制构件的生命周期,提高了用户应用程序的安全性,降低了资源泄漏的可能;通过智能指针能够检查接口的类型安全性,消除潜在的错误。其实施主要通过创建可连接对象和接收器对象,并建立起两者的联系向接收器对象注册客户自己实现的事件方法AddEventCallbackHandler ()以及向接收器对象注销客户自己实现的事件方法,及断开客户与可连接对象的连接事件方法Re 2

moveEventCallbackHandler ()来实

现。

2.4 CAR 智能指针的实现实例

CAR 智能指针是一种类智能指针,是对构件类的

封装,构件类指的是一个构件中定义的类。在下文中提到的智能指针一律指类智能指针。

在CAR 中,类智能指针表现为类,这个类有若干个成员变量,每个成员变量用来指向对象的一个接口,成员变量的数目等于CAR 对象实现的接口个数,成员变量和构件对象实现的接口一一对应。通过类智能指针,可以调用构件对象实现的所有接口方法[4]。

类智能指针的表示形式:CxxxRef ,其中Cxxx 表示类名。一个构件中定义的类分别对应一个相应的类智能指针。

(1)避免用户忘记释放使用EzCreateObject/new

?

11?第2期 叶 蓉等:运用CAR 智能指针实现Callback 机制

创建的类对象[5];

(2)如果该构件类有回调接口,可以直接用智能指针注册回调事件处理函数[5];

(3)使用智能指针可以方便地访问该构件类的所有接口方法。不需要用QueryInterface/Query查询接口[5]。

class CSmartpointerSampleRef

{

public://类CSmartpointerSamepleRef的方法声明

 ECODE SampleEvent();

 ECODE AddSampleCallbackEvent Handler(ECODE(3)(POB2 J ECT));

 ECODE RemoveSampleCallbackEvent Handler(ECODE(3) (POBJ ECT));

public://运算符重载

 operator IObject3(){return m-pObj;}

 operator ISampleEvent3(){return m-p ISampleEvent;}

 operator ICallbackSink3(){return m-sink;}

 IObject33operator&(){return&m-pObj;}

 CSmartpointerSampleRef&operator=(IObject3pObj); public://智能指针特定的方法

 BOOL ObjIsValid();

 ECODE ObjRefer To(POBJ ECT pObj);

 ECODE ObjInstantiate(PDOMAININFO pDomainInfo=CTX-SAME-DOMAIN);

public://构造函数和析构函数

 CSmartpointerSampleRef():

m-pObj(NULL),

m-p ISampleEvent(NULL){}

 ~CSmartpointerSampleRef(){this->ObjDispose();} private://定义私有变量

 IObject3m-pObj;

 ISampleEvent3m-p ISampleEvent;

 CallbackSinkRef m-sink;

private://防止特定的方法被调用

 CSmartpointerSampleRef(const CSmartpointerSampleRef&ref) {}

 CSmartpointerSampleRef&operator=(const CSmartpointer SampleRef&ref){return3this;}

};

INL INE ECODE CSmartpointerSampleRef::SampleEvent() {return m-p ISampleEvent->SampleEvent();}

INL INE ECODE CSmartpointerSampleRef::AddSampleCall2 backEvent Handler(

 ECODE(3fn)(POBJ ECT))//对注册回调事件进行封装{EzMultiQI mq={&IID-IObject,NULL,NOERROR};

 ec=EzCreateObject Ex(CLSID-CSmartpointerSample,pDomain2 Info,1,&mq);

 if(FAIL ED(ec))return ec;

 ec=this->ObjRefer To(mq.pObject);

mq.pObject->Release();

 ec=pObj->QueryInterface(IID-ICSmartpointerSample, (POBJ ECT3)&m-p ICSmartpointerSample);

 if(FAIL ED(ec))goto Error Exit;

ec=EzCreateObject(CLSID-CSmartpointerSampleSink,

CTX-SAME-DOMAIN,IID-ICallbackSink,(POBJ ECT3)&m-sink);

 if(FAIL ED(ec))goto Error Exit;

 ec=m-sink.Connect(pObj);

 if(FAIL ED(ec))goto Error Exit;

 return this->AddSampleCallbackEvent Handler(NULL, (PVOID)fn);

Error Exit:

 this->ObjDispose();

 return ec;

}

INL INE ECODE CSmartpointerSampleRef::RemoveSample2 CallbackEvent Handler(

 ECODE(3fn)(POBJ ECT))//对注销回调事件进行封装

{if(m-p ISampleEvent){

m-p ISampleEvent->Release();

m-p ISampleEvent=NULL;}

 if(m-pObj){

m-pObj->Release();

m-pObj=NULL;}

 if(m-sink.ObjIsValid()){

m-sink.Disconnect();

m-sink.ObjDispose();}

return this->RemoveSampleCallbackEvent Handler(NULL, (PVOID)fn);}

INL INE CSmartpointerSampleRef&CSmartpointerSampleRef::op2 erator=(IObject3pObj)

{

 this->ObjRefer To(pObj);

 return3this;

}

//智能指针类的ObjIsValid方法实现,判断智能指针是否有效,此方法为内部方法

INL INE BOOL CSmartpointerSampleRef::ObjIsValid()

{

 if(m-pObj){

if(TRU E&&m-p ISampleEvent)return TRU E;

return NOERROR==this->ObjRefer To(m-pObj);}

 return FALSE;

}

//智能指针类ObjRefer To方法实现,初始化智能指针类的接口函数,此方法为内部方法

INL INE ECODE CSmartpointerSampleRef::ObjRefer To(POBJ E2

(下转第16页)

Statement接口提供了3种执行SQL语句的方法: executeQuery,executeUpdate和execute。使用哪一个方法由SQL语句所需产生的内容决定。方法execute2 Query用于产生单个结果集的语句,例如SEL ECT语句。方法executeUpdate用于执行INSERT,UPDA TE 或DEL ETE语句以及SQL DDL(数据定义语言)语句,例如CREA TE TABL E和DROP TABL E。INSERT, UPDA TE或DEL ETE语句的效果是修改表中零行或多行中的一列或多列。executeUpdate的返回值是一个整数,指示受影响的行数(即更新计数)。对于CRE2 A TE TABL E或DROP TABL E等不操作行的语句,ex2 ecuteUpdate的返回值总为零。方法execute用于执行返回多个结果集、多个更新计数或二者组合的语句。执行语句的所有方法都将关闭所调用的Statement对象的当前打开结果集(如果存在)。这意味着在重新执行Statement对象之前,需要完成对当前ResultSet对象的处理。应该注意,继承了Statement接口中所有方法的PreparedStatement接口都有自己的executeQuery, executeUpdate和execute方法。Statement对象本身不包含SQL语句,因而必须给Statement.execute方法提供SQL语句作为参数。PreparedStatement对象并不将SQL语句作为参数提供给这些方法,因为它们已经包含预编译SQL语句。CallableStatement对象继承这些方法的PreparedStatement形式。

(4)处理对数据库的查询结果。

对authorResults对象进行处理后,才能将查询结果显示给用户。authorResults对象包括一个由查询语句返回的一个表,这个表中包含所有的查询结果。对authorResults对象的处理必须逐行进行,而对每一行中的各个列,可以按任何顺序进行处理。ResultSet类的一套get方法(这些get方法可以访问当前行中的不同列)提供了对这些行中数据的访问,并可将结果集中的SQL数据类型转换为Java数据类型。

综上所述,即可实现利用JDBC-ODBC桥在Java 中进行数据库的查询。

3 结 语

讨论了利用Java语言的JDBC API和JDBC-ODBC桥完成数据库的SQL查询的方法。在此基础上可以构造更为复杂的查询,以满足用户的不同需求。

参考文献:

[1] 李 诚,王 兵.Java2简明教程[M].北京:清华大学出

版社,2004.

[2] 王克宏,张炳文.Java语言SQL接口———JDBC编程技术

[M].北京:清华大学出版社,2001:234-262.

[3] 刘 欣.基于Servlet和JDBC的Web数据库访问方案[J].

山东电子,2003(1):18-21.

[4] 刘 巍,唐学兵.利用Java的多线程技术实现数据库的访

问[J].计算机应用,2002(12):121-123.

[5] Java2SD K.Standard edition documentation version1.3.1

[M].US:SUN Microsystems,Inc,2003.

[6] Oram,Andy.Database programming with JDBC&Java pa2

perback book[M].[s.l.]:O’Reilly&Associates,Inc,2000.

 

(上接第12页)

CT pObj)

{

 ECODE ec;

 if(NULL==m-pObj){

m-pObj=pObj;

pObj->AddRef();

 }

 else if(pObj!=m-pObj){

this->ObjDispose();

m-pObj=pObj;

pObj->AddRef();

 }

}

3 结 语

用户要使用智能指针,只需采用宏定义#define-SMARTCLASS将相关智能指针对象引入代码,在实现回调机制时,只需要调用智能指针相关方法完成简单的注册工作就可以使用回调事件,在使用完毕后也只需调用智能指针的相关方法注销该回调事件即可。使用CAR智能指针可大大简化Callback机制的实现复杂度。

参考文献:

[1] K oretide.Elastos2.0Manual[M/OL].2007.http://www.

https://www.doczj.com/doc/9a16747004.html,/download/download.php?id=2.

[2] Pan https://www.doczj.com/doc/9a16747004.html,’s Principle and COM’s Application[M].Bei2

jing:The Tsinghua Press,1999.

[3] Rogerson D.Inside COM:Microsoft’s Component Object Mo2

del[M].[s.l.]:Microsoft Press,1999.

[4] Eckel B.Thinking in C++(Second Edition)[M].[s.l.]:

Prentice Hall,2002.

[5] K oretide.Website[EB/OL].2007.http://www.koretide.

https://www.doczj.com/doc/9a16747004.html,.

(完整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类型的对象,这

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/9a16747004.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/9a16747004.html,e_count()); // (C) 设置第一个指针为空。 mySample.reset(); printf("The Sample now has %i references\n", https://www.doczj.com/doc/9a16747004.html,e_count()); // 一个引 用 // 当mySample2离开作用域的时候,对象只有一个引用的时候自动被删除。 } 在(A)中在堆栈重创建了CSample类的一个实例,并且分配了一个shared_ptr指针。对象mySample入下图所示: 然后我们分配了第二个指针mySample2,现在有两个指针访问同一个数据。 我们重置第一个指针(将mySample设置为空),程序中仍然有一个Csample实例,mySample2有一个引用指针。 只要当最有一个引用指针mySample2退出了它的作用域之外,Csample这个实例才被销毁。 当然,并不仅限于单个Csample这个实例,或者是两个指针,一个函数,下面是用shared_ptr的实例: 用作容器中。

软件类笔试试题

什么是编译? 编译器是将一种语言翻译为另一种语言的计算机程序。编译器将源程序(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++演化过程的大部分时间里,我一直把范型程序设计以及支持它的语言特性划归在“数据抽象”的大标题之下。

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

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;

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接口读写数据。 ⑤断开连接。

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),但实际上拷贝赋值的要求也不是强制的,原

第七讲:用ADO技术实现对数据库的查询操作

第七讲:用ADO技术实现对数据库的查询操作 上一讲我们已经学会了如何使用ADO中的Excute函数执行非查询的数据库操作,那么我们如何才能够实现在应用程序中执行SELECT查询操作,并且将数据库中查询到的结果返回到应用程序中好让我们使用C++进行操作呢?接下来让我们一起来看看吧! 【ADO实现查询操作的原理】 在上一讲中我们学习到可以通过Connection对象以及Command对象中的Excute函数执行SQL语句实现非查询的数据库操作。同样的,我们也可以使用Excute函数执行SQL实现查询的数据库操作。 当然这并不是重点所在,重点是我们使用SELECT语句对数据库进行查询之后将会得到查询结果,而这些查询结果是单纯的保存在数据库中的,应用程序不能够直接得到。那么如何才能够获得这些查询的数据呢? 在ADO技术中,我们通过Recordset(记录集)对象保存这些查询的数据,而这些数据将会通过Excute返回值的形式返回到记录集中。我们若想使用Recordset对象,就必须要使用与Recordset相关的智能指针类型。在C++中,使用_RecordsetPtr类型表示智能指针。 【_RecordsetPtr智能指针】 _RecordsetPtr智能指针是在ADO技术中使用的特殊的智能指针类型,它指向用于保存查询结果的Recordset对象。通常我们在执行SQL语句进行查询时,所返回的结果是一张表格(即使是一个单元格也一样),故此Recordset对象也采用表格的存储方式将数据库服务器中查询到的结果返回到应用程序中。 【实现查询操作的步骤】 Step1:建立可靠的数据库连接 Step2:通过Excute函数执行相关的SQL语句,并使用Recordset对象的智能指针对象接收Excute函数执行的返回值 Step3:通过_RecordsetPtr读取记录集中的内容 【获取记录集】 那么如何获取查询的记录集呢?其实很简单,我们只需要在执行查询时,使用一个_RecordsetPrt类型的智能指针对象接收Excute函数的返回值即可。代码如下: 其中Records是使用_RecordsetPtr定义的智能指针对象,CommandString是需要被执行的查询操作。 [例] 查询数据库中所有学生的信息,并接收结果集

设计模式精解-GOF23种设计模式解析(VS2012重写实现包含Linux-Makefile)-代码和原文档已插入本文档

设计模式精解-GOF23种设计模式解析(VS2012重写实现包含Linux-Makefile)-代码和原文档已插入本文档

设计模式笔记(C++) 一、创建型 Factory:工厂 1、定义创建对象的接口,封装了对象的创建 2、使得具体化类的工作延迟到了子类中 3、Factory模式正如我在相应的文档中分析的是为一类对象提供创建接口或者延迟对象的创建到子类中实现。

AbstractFactory:抽象工厂 1、创建一组相关或者相互依赖的对象 2、AbstractFactory模式是为创建一组(有多类)相关或者依赖的对象提供创建接口 3、AbstractFactory模式通常都是使用Factory模式实现(ConcreateFactroy)

Singleton:单例 1、Singleton模式保证一个类仅有一个对象,并提供一个访问它的全局访问点。 2、全局变量不能防止实例化多个对象。 3、全局变量将使得对象在无论是否用到都要被创建。

Builder:创建者 1、Builder模式的意图是非常容易理解、间接的:将一个复杂对象的构建与它的表示分离,使用同样的构建过程可以创建不同的表示(在示例代码中可以通过传入不同的参数实现这一点)。Builder模式和AbstractFactory模式在功能上很相似,因为都是创建大的复杂的对象,它们的区别是:Builder模式强调的是一步步创建对象,并通过相同的创建过程可以获得不同的结果对象,一般来说Builder模式中对象不是直接返回的。而在AbstractFactory模式中对象是直接返回的,AbstractFactory模式强调的是为创建多个相互依赖的对象提供一个同一的接口。

C++的String类及其成员函数和智能指针专题

本文作者:黄邦勇帅 本文是学习C++的附加内容,主要介绍了C++中的string类的各种成员函数,及成员函数的功能与作用,是作为学习C++的参考使用的。 本文内容完全属于个人见解与参考文现的作者无关,其中难免有误解之处,望指出更正。 声明:禁止抄袭本文,若需要转载本文请注明转载的网址,或者注明转载自“黄邦勇帅”。 主要参考文献: 1、C++.Primer.Plus.第五版.中文版[美]Stephen Prata著孙建春韦强译人民邮电出版社2005年5月 2、C++.Primer.Plus.第四版.中文版Stanley B.Lippman、Barbara E.Moo著李师贤等译人民邮电出版社2006年3月 3、C++.Primer.Plus.第三版.中文版Stanley B.Lippman等著潘爱民张丽译中国电力出版社2002年5月 4、C++入门经典第三版[美]Ivor Horton著李予敏译清华大学出版社2006年1月 5、C++参考大全第四版[美]Herbert Schidt著周志荣朱德芳于秀山等译电子工业出版社2003年9月 6、21天学通第四版C++ [美]Jesse Liberty著康博创作室译人民邮电出版社2002年3月 第20章string类 1、string类用于处理字符串,要使用string类需要包含string头文件。 2、注意string是一个类,它具有类的特性,也就是说string类有构造函数,有重载的操作符,有成员函数。string对象 可以自动调整大小,但有一些限制,string对象有个最大允许的长度,该长度由string类的静态常量string::nops设定,通常是最大的unsigned int值,在vc++中被设为-1。 3、string类是模板类basic_string类的char具体化版本,basic_string类的原型为:template, class Allocator=allocator > class basic_string{….}; 对于string类具有预定义的具体化版本typedef basic_string string;也就是说string是basic_string模板类的char具体化版本的别名。 4、string类的size_type类型,size_type是string中的配套类型,一般被定义为unsigned类型。可以使用限定名的方法 来使用size_type类型,比如string::size_type a; 5、string类的构造函数:string类有6种形式的构造函数,string类是basic_string类的特化版本,因此他的构造函数就 是basic_string模板类的char特化版本的构造函数,在这里我们省略掉其他复杂的形式,得到以下的string构造函数版本,具体的basic_string模板类的构造函数这里不讨论。 a、string(const char *s);将string对象初始化为s指向的传统C字符串(即以空字符结束的字符串)。比如string one(“hyong”);将string对象one用字符串hyong来初始化。这就意味着可以把char类型的数组转换为string对象,比如string a; char b[]=”ldki”; 则a=b; string c=b;都是正确的。但不能将string对象的字符串转换为char类型的数组。 b、string(size_type n,char c);创建一个包含n个元素的对象,其中每个元素都被初始化为字符c。比如string two(10, ‘c’); 将string对象two初始化包含为十个字符c。这意味着不可以用单个字符来初始化string类型的对象,比如string a=’s’; 将发生错误。 c、string();创建一个默认的string对象,长度为0。比如string three;即表示创建一个长度为0的字符串对象three。 d、string(const string &str, size_type pos=0,size_type n=npos);将string对象初始化为string对象的字符串从pos开始到 结尾的字符,或从pos开始的n个字符。 e、string(const char *s, size_type n);将string对象初始化为s指向的传统C字符串中的前n个字符,即使超出了字符串 的范围,操作仍会进行。比如char all[]=”hyong”; string five(all, 5);表示用字符数组all的前5个字符来初始化string 对象five。注意即使复制的长度超出了数组的长度,操作仍将进行,也就是说如果把5改为10的话,将导致5个无用的字符被复制到对象中。 f、tempaltestring(Iter begin, Iter end);将string对象初始化为[begin, end]间的字符,其中begin和end就像 指针,用于指定位置,范围包括begin在内,但不包括end,注意不包括end。还要注意begin和end被看着指针,也就是说char all[ ]=”hyongilfmm”; string seven(all+2, all+4)将使用从第all+2的字符o开始到第all+3的字符n初始化对象seven,最后seven为”on”。因为字符串从0开始计数,所以这里从第3个字符开始。而all+3指的是第4个字符,注意all+4指的是第5个字符,这里不以第5个字符g结束,因为该构造函数不包括end在内。还要注意,对begin和end被看着指针指向某一位置,也就是说string a=”hyong”;string b(a+3, a+5);是错误的,因为a是string类对象,不是指针,所以a+3没有意义,所以这里应这样string b(&a[3], &a[5])这里a[3]是一个char值,&a[3]是一个地址。 6、注意,不能用单个字符来初始化string对象,比如string a=’d’;将是错误的,但是string a(1,’d’)是正确的,这里将把’d’ 初始化为”d”。

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" 返回的指针被丢失,因为它没有被存入我们期望能阻止

BAT经典面试题汇总

STL中vector的实现原理(衍生:Map, Set等实现原理) 参考答案 vector的数据安排以及操作方式,与array非常相似。两者的唯一区别在于空间的运用的灵活性。array是静态空间,一旦配置了就不能改变;要换个大(或小)一点的房子,可以,一切琐细都得由客户端自己来:首先配置一块新空间,然后将元素从旧址一一搬往新址,再把原来的空间释还给系统。vector是动态空间,随着元素的加入,它的内部机制会自行扩充空间以容纳新元素。因此,vector的运用对于内存的合理利用与运用的灵活性有很大的帮助,我们再也不必因为害怕空间不足而一开始要求一个大块头的array了,我们可以安心使用array,吃多少用多少。 vector的实现技术,关键在于其对大小的控制以及重新配置时的数据移动效率。一旦vector的旧有空间满载,如果客户端每新增一个元素,vector的内部只是扩充一个元素的空间,实为不智。因为所谓扩充空间(不论多大),一如稍早所说,是”配置新空间/数据移动/释还旧空间“的大工程,时间成本很高,应该加入某种未雨绸缪的考虑。稍后我们便可看到SGI vector的空间配置策略了。 另外,由于vector维护的是一个连续线性空间,所以vector支持随机存取。 注意:vector动态增加大小时,并不是在原空间之后持续新空间(因为无法保证原空间之后尚有可供配置的空间),而是以原大小的两倍另外配置一块较大的空间,然后将原内容拷贝过来,然后才开始在原内容之后构造新元素,并释放原空间。因此,对vector 的任何操作,一旦引起空间重新配置,指向原vector的所有迭代器就都失效了。这是程序员易犯的一个错误,务需小心。 给定N张扑克牌和一个随机函数,设计一个洗牌算法 参考答案 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 void shuffle(int cards[],int n) { if(cards==NULL) return ; srand(time(0)); for(int i=0;i

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" < x(new test);

后台开发面试问题整理

后台开发面试问题整理 https://www.doczj.com/doc/9a16747004.html,/jcjc918/article/details/504344622016 最近实习招聘又开始了,被一些师弟问了面试会问到的问题,于是想把之前实习、校招被问过的问题整理出来,希望对需要的人有帮助。虽然下面很多问题,但面试时可以问的问题是一个无限集,而且因人而异,只能作为一定的参考,如果把所有知识面都掌握得很牢固那问什么都没问题:)这里的问题也不是说要所有都能答得上来,能答大部分我觉得BAT 就没啥问题了。 个人背景:本科,偏工程,技术栈C++,接触过Python、Java、PHP、Go 面试职位:后台开发、C++工程师等 后续再看有没有必要标注哪些问得比较频繁,需不需要回答参考。 C++ static 关键字有哪些用法 说说继承和组合的概念?什么时候应该用继承?什么时候

应该用组合 C++ 的菱形继承会发生什么问题?画出对应的内存布局 说说对C++ 智能指针的了解 说说虚函数实现机制 如果父类中仅有方法,子类有一个int 变量,这时候sizeof 是多大 指针一定是4 个字节吗 #define 和inline 函数的区别是什么 const static 在哪里初始化 派生类的构造函数和析构函数执行顺序 什么情况下基类的析构函数没有被调用 如何生成静态库?如何生成动态库 如何用gdb 调试 coredump 查看,core 文件分析 如何调试运行中的程序 运行了几天的程序崩掉,如何分析错误 如何编写makefile 编译器的编译过程?链接的时候做了什么事?在中间层优 化时怎么做? STL 各容器如何实现 适配器是用来做什么的 queue 如何实现

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