加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Cocos2dx 3.4内存管理机制——RefPtr

发布时间:2020-12-14 20:39:50 所属栏目:百科 来源:网络整理
导读:—简介: 2dx3.1 引入了智能指针 RefPtrT , RefPtrT 是基于 RAII 实现的,在 RAII 中,动态资源的持有发生在一个对象的生命周期之内,也就是在对象的构造函数中分配内存,对象的析构函数中释放内存,这样做也就是把动态内存与自动变量进行绑定,通过自动变

—简介:2dx3.1引入了智能指针RefPtr<T>RefPtr<T>是基于RAII实现的,在RAII中,动态资源的持有发生在一个对象的生命周期之内,也就是在对象的构造函数中分配内存,对象的析构函数中释放内存,这样做也就是把动态内存与自动变量进行绑定,通过自动变量的构造与析构函数来管理动态内存,这也就是各种智能指针的基本原理。

—特点:1、模仿C++11std::shared_ptr实现

2、无法保证线程的安全

3、更加轻量级

—用处:用于管理游戏中数据的内存

游戏中的数据,例如__String,或者自定义的某个数据类

2dx中明明已经有autorelease的内存管理方法了,为何还要添加RefPtr<T>

因为数据对象创建后,调用了autorelease方法,若数据对象未被引用,则会在每一帧结束后被释放,对于需要经常调用的数据,这显然是我们不想要见到的,那么有什么方法可以解决呢?

一、直接retain,不要时release,这种方法显然不好,要不2dx的内存管理直接用C++newdelete就好了。

二、将其添加至某个节点下作为子节点,我最初认为这种方法应该是不错的了,但是后 来想了一想,首先,想成为子节点,自身就必须继承自Node,而简单的数据对 象并不需要Node的特性,因此也不是十分理想

通过上述叙述,2dx中现有的autorelease方法显然不适用于游戏中数据的管理,但是对于游戏中的UI元素来说,还是十分好的。

RefPtr<T>的工作流程简析

RefPtr<__String>ref2(String::create(“Hello”));

上述语句可分为三部分来看,首先数据类型RefPtr<__String>,表示智能指针指向的内存是__String类型的;其次String::create(“Hello”),构造函数的参数,返回__String对象,最后ref2(String::create(“Hello”))RefPtr<__String>对象的创建,调用了RefPtr<__String>的构造函数,在构造函数中,首先将String::create(“Hello”)赋值给RefPtr<T>中的Ref对象_ptr,接着再对_ptr进行retain();这样智能指针的创建过程就完成了。

在游戏的运行过程中,第一帧结束后,_ptr便release一次了,因此此时_ptr的引用计数为1,当ref2对象析构时,会对_ptr进行release,并把_ptr置空,此时动态分配的数据便被释放了。

当然在游戏的运行过程中,数据对象可能需要被其他类进行引用,因此数据对象也是需要拷贝的,智能指针在这方面与引用计数有些相似,拷贝一次引用计数加一,这也是为什么智能指针指向的数据类型只能是继承自Ref的原因了。

—部分源码解析:

1//模板类,T可以是任意继承自Ref的类型,否则无法对引用计数进行操作

template<typenameT>classRefPtr

{

}

2//空构造函数,让智能指针指空

inlineRefPtr()

:

_ptr(nullptr)

{

}

3//转移构造函数(自己命名的,后续类似),当形参为智能指针的左值时,意味着内存的管理是被转移而不是被共享

inlineRefPtr(RefPtr<T>&&other)

{

_ptr=other._ptr;

other._ptr=nullptr;

}

4//转换构造函数(自己命名的,后续类似),将T*类型的变量转换为RefPtr<T>类型的,同时对_ptr进行retain操作

inlineRefPtr(T*ptr)

:

_ptr(const_cast<typenamestd::remove_const<T>::type*>(ptr))

{

CC_REF_PTR_SAFE_RETAIN(_ptr);

}

5 //共享构造函数(自己命名的,后续类似),当形参为智能指针的右值时,意味着内存的被另一个RefPtr<T>所共享,改内存的引用计数加一

inlineRefPtr(constRefPtr<T>&other)

:

_ptr(other._ptr)

{

CC_REF_PTR_SAFE_RETAIN(_ptr);

}

6//析构函数,对指向动态内存的_ptr进行释放

inline~RefPtr()

{

CC_REF_PTR_SAFE_RELEASE_NULL(_ptr);

}

—最后:对自定义的数据类型,如需分配动态内存,令其继承自Ref,使用智能指针RefPtr来管理其内存的释放

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读