首页 > 代码库 > ARPG客户端中场景对象体系设计

ARPG客户端中场景对象体系设计

一、场景对象体系

 

二、场景对象生命周期管理

场景对象的生命周期,不适合采用原始的c++管理方式, 即由使用者自己负责删除。而应该采用引用计数方式, 自动负责删除。

采用引用计数方式, 目前用法比较广的分两类:

1、智能指针, 如boost::shared_ptr, 这种方式原理是基于c++对象的生命周期和析构函数来实现的, 而且引用计数是由智能指针对象保存的。在这种方式下, 对象的传递和引用都是使用智能指针对象, 例如:

 class A; typedef boost::shared_ptr<A> TAPtr;  //B需要保留对A的引用 class B { public:     void AccessA(TAPtr a)     {         m_a = a;                  //省略     };       private:     TAPtr m_a; };      //C不需要保留对A的引用, 而仅仅是在某个接口中要访问A class C { public:     void AccessA(TAPtr a)     {         //省略, 访问a     };  }; 

 这种方式的优点:

使用者没有任何负担。

缺点:

[1] 效率低。

[2] 不方便暴露对象给lua使用。

2、cocos2d中的Ref方式, 即由对象自身来保存当前的引用数, 并且由对象的使用者自己来负责增加引用数retain和减少引用数release。 在这种方式下, 对象的传递和引用都是使用对象指针来实现, 例如:

 class A: public Ref;  //B需要保留对A的引用 class B { public:    ~B()    {        if(m_a)        {            m_a.release();            m_a = NULL;        }    }         void AccessA(A *a)     {         m_a = a;         m_a.retain();                  //省略     };       private:     A *m_a; };      //C不需要保留对A的引用, 而仅仅是在某个接口中要访问A class C { public:     void AccessA(A *a)     {         //省略, 访问a     };  }; 

 

这种方式的优点是:

[1] 效率高, 无论是传递、访问还是对于引用计数的操作(由使用者本身决定是否要调用retain和release)。

[2] 方便把对象暴露给Lua使用。

缺点是:

增 加了使用者自身的负担, 很容易造成内存泄露, 这正是因为由使用者本身决定是否要调用retain和release引起的。基于相同的原因, 如果要用容器(比如list, vector等)来保存对象时, 标准库中的容器没办法直接使用, 而必须封装, 或者在插入和删除元素是, 手动调用元素的retain和release.

ARPG客户端中场景对象体系设计