【深入了解cocos2d-x 3.x】内置数据结构(1)——智能指针

【深入了解cocos2d-x 3.x】内置数据结构(1)——智能指针,第1张

概述智能指针在C++11的标准中已经存在了,分别是unique_ptr,shared_ptr,weak_ptr,其中最常用的应该是share_ptr,它采用引用计数的方式管理内存,当引用计数为0的时候,自动释放内存,但是由于shared_ptr考虑到了线程安全,所以会存在有较大的性能损失。所以在实时游戏开发中,往往不会用到shared_ptr。 在cocos2d-x3.2以及更高的版本中,cocos2

智能指针在C++11的标准中已经存在了,分别是unique_ptr,shared_ptr,weak_ptr,其中最常用的应该是share_ptr,它采用引用计数的方式管理内存,当引用计数为0的时候,自动释放内存,但是由于shared_ptr考虑到了线程安全,所以会存在有较大的性能损失。所以在实时游戏开发中,往往不会用到shared_ptr。

在cocos2d-x3.2以及更高的版本中,cocos2d-x提供了自己的智能指针方案——RefPtr,这套方案实际上也是模仿C++11中的shared_ptr机制实现的,他结合了Cocos2d-x自身的引用计数来管理内存,当然为了性能,他牺牲了线程安全(cocos2d-x的引用计数不支持线程安全)。

下面看看cocos2d-x中智能指针的源码,首先是构造函数

    inline RefPtr()    :        _ptr(nullptr)    {            }        inline RefPtr(RefPtr<T> && other)    {        _ptr = other._ptr;        other._ptr = nullptr;    }    inline RefPtr(T * ptr)    :        _ptr(const_cast<typename std::remove_const<T>::type*>(ptr))     // Const cast allows RefPtr<T> to reference objects marked const too.    {        CC_REF_PTR_SAFE_RETAIN(_ptr);    }        inline RefPtr(std::nullptr_t ptr)    :        _ptr(nullptr)    {            }        inline RefPtr(const RefPtr<T> & other)    :        _ptr(other._ptr)    {        CC_REF_PTR_SAFE_RETAIN(_ptr);    }

RefPtr提供了多个构造函数,可以用默认构造函数声明一个空智能指针,用别的指针来声明一个智能指针,也提供了移动构造函数将内存偷过来,复制构造函数保持内存的强引用。构造函数最为重要的莫过于CC_REF_PTR_SAFE_RETAIN宏了,它是智能指针专用的宏,在外部是引用不到的。实现如下
#define CC_REF_PTR_SAFE_RETAIN(ptr)\    \    do\    {\        if (ptr)\        {\            const_cast<Ref*>(static_cast<const Ref*>(ptr))->retain();\        }\    \    }   while (0);
核心就是retain,保持一个强引用。

下面是声明智能指针的用法

	//inline RefPtr()	RefPtr<int> a;	//inline RefPtr(T * ptr)	RefPtr<int> b(new int);	//inline RefPtr(const RefPtr<T> & other)	RefPtr<int>c(b);	//inline RefPtr(RefPtr<T> && other)	RefPtr<int>d(std::move(b));	//inline RefPtr(std::nullptr_t ptr)	RefPtr<int>d(nullptr);

接下来看看析构函数
    inline ~RefPtr()    {        CC_REF_PTR_SAFE_RELEASE_NulL(_ptr);    }

析构函数就简单多了,只有一个,具体还是要到宏里面。
#define CC_REF_PTR_SAFE_RELEASE_NulL(ptr)\    \    do\    {\        if (ptr)\        {\            const_cast<Ref*>(static_cast<const Ref*>(ptr))->release();\            ptr = nullptr;\        }\    \    }   while (0);
实际上就是对其release并且置空。

另外,也提供了移动赋值函数以及赋值函数。

    inline RefPtr<T> & operator = (RefPtr<T> && other)    {        if (&other != this)        {            CC_REF_PTR_SAFE_RELEASE(_ptr);            _ptr = other._ptr;            other._ptr = nullptr;        }                return *this;    }        inline RefPtr<T> & operator = (T * other)    {        if (other != _ptr)        {            CC_REF_PTR_SAFE_RETAIN(other);            CC_REF_PTR_SAFE_RELEASE(_ptr);            _ptr = const_cast<typename std::remove_const<T>::type*>(other);     // Const cast allows RefPtr<T> to reference objects marked const too.        }                return *this;    }        inline RefPtr<T> & operator = (std::nullptr_t other)    {        CC_REF_PTR_SAFE_RELEASE_NulL(_ptr);        return *this;    }

第一个是移动赋值函数,第二个是赋值函数,第三个是置空专门用于下列场景
	RefPtr<int> b(new int);	b = nullptr;


RefPtr还重载了指针 *** 作符 *和-> 方便直接调用内部指针,所以其使用方法与普通指针一样。也提供了get方法获取到指针

    inline operator T * () const { return reinterpret_cast<T*>(_ptr); }        inline T & operator * () const    {        CCASSERT(_ptr,"Attempt to dereference a null pointer!");        return reinterpret_cast<T&>(*_ptr);    }        inline T * operator->() const    {        CCASSERT(_ptr,"Attempt to dereference a null pointer!");        return reinterpret_cast<T*>(_ptr);    }        inline T * get() const { return reinterpret_cast<T*>(_ptr); }

还重载了一系列的 *** 作符,这里就不做分析了,最后还有一个比较关键的函数,weakAssign,它对保持对一个指针的弱引用,实现如下:
    inline voID weakAssign(const RefPtr<T> & other)    {        CC_REF_PTR_SAFE_RELEASE(_ptr);        _ptr = other._ptr;    }

相对于其他的复制函数,他少了retain *** 作,说明它并不保持对other的强引用,但是析构的时候我们发现,依旧会release一次,那么这个函数会有什么奇妙的作用呢。看下面的函数片段
	voID a()	{		RefPtr<Texture2D> l;		l.weakAssign(new Texture2D);		// -- doSomething		return;	}

函数中并没有delete,但是依旧不会造成内存泄露,当然,还有一种方法也不会造成内存泄露,也就是
auto aa = new Texture2D;	aa->autorelease();
但是这一种方法的释放时机是在一帧的结束,而智能指针的释放时机是函数的结束,所以相较于下一种方法,智能指针会效率更高 总结

以上是内存溢出为你收集整理的【深入了解cocos2d-x 3.x】内置数据结构(1)——智能指针全部内容,希望文章能够帮你解决【深入了解cocos2d-x 3.x】内置数据结构(1)——智能指针所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1052094.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-25
下一篇2022-05-25

发表评论

登录后才能评论

评论列表(0条)

    保存