深入FDO----内存管理机制

 

调用某些FDO的函数,如创建方法,需要申请内存,而这些内存需要在适当的时机释放,以免内存泄漏。FDO使用了引用计数的方式来实现管理对象的生命周期,每个对象都维护着一个引用计数,只有当这个对象的引用计数变为0时,才会去释放这个对象。所以,FDO中每个类都从FdoIDisposable类继承而来的,FdoIDisposable定义了Release()AddRef()方法。调用方法Release()会将当前对象的引用计数减1,然后判断这个对象的引用计数是否变为0了,如果是则释放这个对象;调用方法AddRef()会将当前对象的引用计数加1。为了防止用于调用操作符delete释放一个对象,FDO中所有类的析构函数都是protected的,调用者只能通过调用Release()方法来释放对象。

1.1.1        内存管理相关的宏

为了简化对象的创建和释放,FDO预定义了如下两个宏。

1.   FDO_SAFE_RELEASE (*ptr)

如果“*ptr”不是空指针,FDO_SAFE_RELEASE就会调用“*ptr” 所指对象的Release()方法,而后把指向该对象的指针赋为NULL。该宏定义的实现为:

#define FDO_SAFE_RELEASE(x) {if (x) (x)->Release(); (x) = NULL;}

该宏的使用方式如下所示。

FdoFeatureClass* pBase = myClass->GetBaseClass();

...

FDO_SAFE_RELEASE(pBase);

2.   FDO_SAFE_ADDREF (*ptr)

如果“*ptr”不是空指针,FDO_SAFE_ADDREF就会调用“*ptr”所指对象的AddRef()方法。该宏定义的实现为:

#define FDO_SAFE_ADDREF(x) ((x != NULL) ? (x)->AddRef(), (x): (NULL))

例如当执行代码FDO_SAFE_ADDREF(value)时,如果valueNULL那么返回值也是NULL,否则把value所指对象的引用计数加一并返回value

1.1.2        智能指针FdoPtr

FdoPtr是用来协助内存管理的智能指针,它是一个C++模板类,它模板参数必须继承自FdoIDisposable的类。用户可以把FDO对象用该指针加以封装,这样,对象就可以在FdoPtr出作用域时自动释放。以下是使用FdoPtr的一个例子:

FdoPtr<FdoFeatureClass> pBase = myClass->GetBaseClass();

...

上面的代码无需调用FDO_SAFE_RELEASE,在FdoPtr销毁之前,pBase会调用FdoFeatureClass 对象的Release()方法。

如果由于某些原因我们想对FdoPtr调用FDO_SAFE_RELEASE,我们必须得到FdoPtr封装的指向对象的指针,然后把该指针传入FDO_SAFE_RELEASE。用户可以把FdoPtr用于自定义的类,当然这些类需要继承自FdoIDisposable,并且要实现Dispose()方法。

如果你把调用FDO方法返回的指针赋给了一个非智能指针,那么你应该把这个非智能指针再赋值给一个FdoPtr,例如:

FdoLineString* p = gf.CreateLineString(...);

FdoPtr <FdoLineString> p2 = FDO_SAFE_ADDREF(p);

智能指针为内存管理带来很大的便利,但是如果使用不当反而会产生一些问题,一个比较常见的问题就是链式调用,链式调用会导致返回的指针无法释放。假设pclassDef是指向类FdoClassDefinition实例的一个指针,那么如下的代码会导致两处内存泄露。

psz = pclassDef ->GetProperties()->GetItem(0)->GetName());

正确的用法为:

FdoPropertyDefinitionCollection* pprops = pclassDef -> GetProperties();

FdoPropertyDefinition* ppropDef = pprops->GetItem(0);

psz = propDef->GetName();

ppropDef->Release();

pprops->Release();

或者 (使用FdoPtr)

FdoPtr<FdoPropertyDefinitionCollection> pprops = pclassDef-> GetProperties();

FdoPtr<FdoPropertyDefinition> ppropDef = pprops-> GetItem(0);

psz = propDef->GetName();

或者(还是使用FdoPtr)

psz = FdoPtr <FdoPropertyDefinition> (FdoPtr <FdoPropertyDefinitionCollection>

(pclassDef->GetProperties())-> GetItem(0))->GetName();

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值