`
sogotobj
  • 浏览: 648247 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

irrlicht引擎源码剖析3 - 引用计数

阅读更多

在研究irrlicht的video driver和scene graph之前,必须先了解在irrlicht中广泛应用的引用计数机制。irrlicht的接口IReferenceCounted实现了引用计数的机制。需要采用引用计数管理的类都会继承这个接口。irr的引用计数最重要的两个接口就是grab()和drop()。

grab()只是简单的将引用计数加一,而drop()是这个机制的核心,当drop()后当引用计数为0时,对象实例通过delete this删除自己从而最终释放了无人再使用的对象。正确的使用grab()和drop()是引用计数机制的核心,当你想长期持有一个对象时,需要grab()他,然后在不再使用的时候drop()他。grab()后,这个对象就不会因为其他地方的drop而被释放掉,因为至少你还有对他的引用。如果只是在一个函数段里面短期的使用一个对象,可以不grab也不drop,当然你要考虑多线程的情况。另外如果对象是你创建的,但你不能决定什么时候释放他,你就应该再把该对象添加到某个对象后调用drop(),这种情况也很常用。比如下面的伪代码:

IImage* pImage = new CImage(...);

pImageManager->add(pImage); //in add, pImageManager will call a grab()

pImage->drop();

这样很容易将对象的创建和释放分开到不同的对象中。

当然引用计数机制也让很多人讨厌,因为用乱了用错了麻烦一大堆。如果是自己创建的对象还好,而irrlicht引擎中提供的对象就要小心对待了。一般说来使用getXXX()得到的对象不需要drop(),当然除非你grab()了。使用createXXX()或你自己new出来的对象,你需要保证他在某个地方被drop()了,实在不放心应该深入引擎的代码看一下,建议使用vld这样的可视化内存泄露监测工具帮助你查找泄露内存的地方。

另外还有两个值得注意的问题

1)IReferenceCounted接口往往是被虚拟继承的,例如

class ISceneManager : public virtual IReferenceCounted

因为使用引用计数的接口和类很多,有可能某个类实现了几个接口,而这几个接口都继承自IReferenceCounted, public virtual继承保证只有一个IReferenceCounted基类对象

例如class CSceneManager : public ISceneManager, public ISceneNode就是这种情况

因为:

class ISceneNode : virtual public io::IAttributeExchangingObject

class IAttributeExchangingObject : virtual public IReferenceCounted

而class ISceneManager : public virtual IReferenceCounted

2)观察一些irrlicht引擎中的接口,接口中没有定义虚拟的析构函数

例如class IMesh : public virtual IReferenceCounted,在include\IMesh.h中

这个接口里面连~IMesh()都没有,更不会有virtual ~IMesh()了。

按照c++通常的思维,如果一个类明确的是要被继承的,需要定义一个virtual析构。那么为什么irrlicht中的很多接口都不定义呢?正因为他是引用计数的。比如,有一个接口IBase和他的子类CDerived。如果这么用

IBase* pBase = new CDerived();

那么当delete pBase时,如果IBase没有虚拟析构,就不会正确执行CDerived的析构了。

但是如果IBase继承自IReferenceCounted,通常我们的用法不会使用delete pBase来释放这个对象了。我们会使用pBase->drop(),问题就在这儿,这个drop()就是IReferenceCounted接口定义的那个,最终会执行delete this,这个this的类型就是调用drop()的对象的类型,这个对象实际是子类的,所以会调用子类的析构函数,从而会进一步调用父类的析构,所以父类没有定义虚拟析构也不要紧了。这就是引用计数的花招。当然irrlicht引擎中有些接口也定义了虚拟析构,这没有影响,这样更安全,即使某人没有用引用计数的方法管理对象的生命周期也不会出问题。我觉得,无论是否使用这样的引用计数机制,最好给父类都加上虚拟析构比较安全,也比较明确。

分享到:
评论

相关推荐

    鬼火引擎源码(irrlicht-1.8.4)

    鬼火引擎源码(irrlicht-1.8.4) 是一个游戏引擎源码,欢迎各位下载学习。以前定价太高了,现在就当作福利送给大家吧。

    irrlicht-1.7.1. 引擎源码

    irrlicht-1.7.1 引擎源码是一个开源的3D图形引擎,专为游戏开发和其他实时3D应用而设计。这个源码库包含了实现高性能3D渲染、物理模拟、输入处理以及各种资源管理的功能。以下是关于irrlicht-1.7.1引擎的一些关键...

    irrlicht 3D 游戏引擎源码

    irrlicht 1.3版本的源码包中,你将找到包括库文件、头文件、示例程序、文档以及可能的编译工具,这些资源可以帮助你深入理解引擎的工作原理,并且快速开始自己的3D项目开发。通过研究这些源码,你可以学习到如何创建...

    irrlicht1.6的帮助手册-英文的

    irrlicht1.6的帮助手册-英文的帮助手册可惜没有中文的!

    最新 irrlicht(鬼火)引擎 源码

    irrlicht-1.7.2.zip irrlicht引擎是一个开源的3D图形引擎,由德国开发者Mario Kicherer创建,其名称"irrlicht"在德语中意为"鬼火",象征着它在3D世界中点亮光明。这个引擎以C++编写,支持多种操作系统,包括...

    irrlicht-1.6引擎全中文注释教程3

    游戏开发初学者可以看看,全中文注释irrlicht-1.6引擎的第一个例子,后面的的例子正在翻译,敬请期待!

    Irrlicht引擎_Android版

    2. **源码准备**:获取Irrlicht引擎的源代码,根据Android平台的需求进行必要的修改和调整。 3. **编译命令**:使用NDK的交叉编译工具链,如`ndk-build`或CMake,执行编译命令,生成适用于Android平台的.so文件。 4....

    3D游戏引擎irrlicht

    1.7.2版本的SDK是一个小巧的24.6MB文件,下载并解压缩后,你会得到一个名为`irrlicht-1.7.2`的目录。在这个目录下,`bin\Win32-VisualStudio`路径中包含了预编译的DLL文件,适用于Visual Studio环境。 如果你打算对...

    irrlicht 引擎

    在irrlicht-1.5版本中,可能包含以下内容: - 源代码:所有irrlicht引擎的源代码,供开发者研究和定制。 - 文档:包括API参考手册、用户指南和开发日志,帮助开发者了解引擎的使用方法和开发过程。 - 示例项目:...

    在Qt中使用Irrlicht3D引擎

    - 下载Irrlicht3D引擎的源码或预编译库,根据你的系统选择合适的版本。 - 将Irrlicht的库文件(通常包括.lib和.dll)以及头文件(.h)添加到你的系统路径或者项目目录下。 2. **创建Qt项目**: - 使用Qt Creator...

    鬼火引擎的最新版本 irrlicht-1.8

    irrlicht-1.8 是鬼火引擎(Irrlicht Engine)的一个重要版本更新。鬼火引擎,也称为 irrlicht,是一款流行的开源3D图形引擎,主要用于游戏开发和其他实时3D应用。这款引擎以其易用性、高效性能以及跨平台支持而受到...

    Irrlicht引擎学习教程

    最后,"引擎及所用编译器地址.txt"文件很可能包含了获取Irrlicht Engine源码和相关编译器的链接,这将帮助你获取最新版本的引擎,以及构建自定义版本的Irrlicht Engine。 总的来说,这个压缩包提供了一个全面的学习...

    Irrlicht Engine__API-Manual.pdf

    Irrlicht Engine 是一款高性能的3D图形渲染引擎,适用于C++程序以及.NET语言的开发环境。它支持多种平台,包括Windows,并且能够利用Direct3D、OpenGL 1.2 或其自带的软件着色器来实现实时渲染,这确保了它在不同...

    Irrlicht引擎例子说明及中文

    Irrlicht引擎是一款开源的3D图形引擎,专为游戏开发和实时三维可视化设计。这个引擎以其易用性、跨平台性和高效性能而受到开发者们的欢迎。"Irrlicht引擎例子说明及中文"压缩包文件提供了关于如何使用Irrlicht引擎的...

    Irrlicht引擎的ai库

    Irrlicht引擎是一款开源的3D图形引擎,以其高效和易用性在游戏开发和实时三维渲染领域被广泛应用。而"Irrlicht引擎的ai库"则是该引擎的一个扩展,专注于实现人工智能(AI)功能,这对于游戏中的角色行为模拟、路径...

    Irrlicht 游戏引擎开发 cooliris 界面(三)

    Irrlicht游戏引擎是一款开源的3D图形库,适用于游戏开发和其他实时三维应用。它以其高效、易用和跨平台的特点而受到开发者欢迎。在"Irrlicht游戏引擎开发 cooliris 界面(三)"这个主题中,我们可能涉及到的是如何...

    用IRRLICHT3D引擎写RPG游戏的框架

    4. **源码分析**:提供的源码中,你可以学习到如何使用Irrlicht引擎创建游戏场景,加载3D模型,实现角色移动、碰撞检测、动画播放等功能。此外,游戏逻辑如敌人AI、任务系统和对话框可能也包含在内。 5. **工程文件...

    Irrlicht 中文支持引擎

    在这个项目中,FreeType源码的使用表明Irrlicht引擎通过集成FreeType库来实现了高质量的文本渲染,特别是对于中文字符的支持。FreeType库的灵活性和高效性使得中文字符能够在屏幕上清晰、流畅地显示,增强了用户体验...

    irrlicht鬼火引擎demo中文文档

    - **Linux环境**:Irrlicht引擎以静态库的形式存在,开发者需要先通过源码目录下的Makefile文件进行编译。编译完成后即可运行\examples目录下的示例程序。 #### 编译需求 - **编译器兼容性**:支持多种编译器,包括...

Global site tag (gtag.js) - Google Analytics