开源要素数据对象FDO的内存管理机制

开源要素数据对象FDO的内存管理机制


发布日期: 2016-10-27 更新日期: 2016-10-27 编辑:黄馨宁 浏览次数: 2666

标签:

摘要: 在调用某些FDO的函数的时候,需要申请内存,并且这些内存应该在适当的时机释放掉,避免发生内存泄露。FDO用引用计数的方式来实现管理对象的生命周期,这样每个对象都维护着一个引用计数,当这个对象的引用计数变为0时,这个对象就会被释放。因此,FDO中每个类都是从Fd...

在调用某些FDO的函数的时候,需要申请内存,并且这些内存应该在适当的时机释放掉,避免发生内存泄露。FDO用引用计数的方式来实现管理对象的生命周期,这样每个对象都维护着一个引用计数,当这个对象的引用计数变为0时,这个对象就会被释放。因此,FDO中每个类都是从FdoIDisposable类继承而来的,FdoIDisposable定义了Release()和AddRef()方法。调用方法Release()会将当前对象的引用计数减1,然后判该对象的引用计数是否位0,如果是那么就释放这个对象;相应的方法AddRef()会将当前对象的引用计数加1。并且为了防止用于调用操作符delete释放一个对象,在FDO中所有类的析构函数都是被保护的,释放对象只能通过调用Release()方法。

一·FDO中内存管理相关的宏

FDO预定义了两个宏用来简化对象的创建和释放。

1. FDO_SAFE_RELEASE (ptr)*

若“ptr”为非空指针,那么FDO_SAFE_RELEASE会调用“ptr”指向的对象的Release()方法,然后把指向该对象的指针赋值为NULL。该宏定义的实现为:

<pre class="brush:py"> define FDO_SAFE_RELEASE(x) {if (x) (x)->Release(); (x) = NULL;} </pre>

该宏的使用方式如下所示: 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)-&gt;AddRef(), (x): (NULL))

二·FDO的智能指针FdoPtr

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

FdoPtr&lt;FdoFeatureClass&gt; pBase = myClass-&gt;GetBaseClass();
...

以上的这段代码不需要对FDO_SAFE_RELEASE进行调用,因为在Fdoptr被销毁前,FdoFeatureClass对象的Release()方法会被pBase调用。

当我们想要用FdoPtr来调用FDO_SAFE_RELEASE时,首先我们要得到FdoPtr封装的指向对象的指针,然后再把该指向对象的指针传入到FDO_SAFE_RELEASE。用户可以用FdoPtr来自定义类,自然,这些类需要从FdoIDisposable继承,且要实现Dispose()的方法。若给一个非智能指针用FDO方法返回的指针赋值,那么就应该把这个非智能指针再给一个FdoPtr赋值,例如:

 FdoLineString* p = gf.CreateLineString(...);
 FdoPtr &lt;FdoLineStringp2 = FDO_SAFE_ADDREF(p);

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

 psz = pclassDef -&gt;GetProperties()-&gt;GetItem(0)-GetName());

正确的用法为:

 FdoPropertyDefinitionCollection* pprops = pclassDef -GetProperties();
 FdoPropertyDefinition* ppropDef = pprops-GetItem(0);
 psz = propDef-&gt;GetName();
 ppropDef-&gt;Release();
 pprops-&gt;Release();
 或者 (使用FdoPtr)
 FdoPtr&lt;FdoPropertyDefinitionCollectionpprops = pclassDef-GetProperties();
 FdoPtr&lt;FdoPropertyDefinitionppropDef = pprops-GetItem(0);
 psz = propDef-&gt;GetName();
 或者(还是使用FdoPtr)
 psz = FdoPtr &lt;FdoPropertyDefinition(FdoPtr &lt;FdoPropertyDefinitionCollection&gt;
 (pclassDef-&gt;GetProperties())-GetItem(0))-&gt;GetName();

关注公众号
获取免费资源

随机推荐


Copyright © Since 2014. 开源地理空间基金会中文分会 吉ICP备05002032号

Powered by TorCMS

OSGeo 中国中心 邮件列表

问题讨论 : 要订阅或者退订列表,请点击 订阅

发言 : 请写信给: osgeo-china@lists.osgeo.org