美文网首页Unreal 技术笔记
Unreal源码阅读(8)SharedPointer

Unreal源码阅读(8)SharedPointer

作者: 子夜书案 | 来源:发表于2019-08-19 19:32 被阅读0次

    发现无论看到哪里都绕不开这个类,那我们就来看看这个类到底有什么玄机。源码

    看注释,就知道它大有来头:

    源码注释

    unreal把c++0x(c++11)里的特性基本上都重实现了一遍,智能指针(smart pointer)也不例外。SharedPointer里就是这些实现的源码。让我们怀着崇高的敬意接着往下看。我们都知道,只有使用C++,那如何合理的进行内存管理就是一项绕不开的话题。c++11里得智能指针,让更多的程序员可以更专注的构建算法和逻辑,而不有过于小心翼翼的担心内存会不会有泄漏。我知道实现原理,但没看过c++11里的实现源码,现在能在unreal里看见,是一个难得的学习机会,我就顺着对智能指针的理解,不完全按照顺序,来一步一步的阅读源码。

    1,引用记数:

    FReferenceControllerBase源码

    引用计数有两个,一个是共享引用计数,一个是弱引用计数。一般的实现是在SharedReferenceCount=0 或者 =1而且引用者是自身时,DestroyObject。上面的源码是ReferenceControllerBase,后面有各种子类的实现。

    那它就在什么情况下,count会变化呢?在这里,unreal设计了一个专门的template struct来实现它。

    Ops template struct

    里面对ThreadSafe和NotThreadSafe分别进行了template的特化,里面的增减操作分别为:

    ThreadSafe模式的AddShared操作

    AddSharedReference:原子级别的递增。

    ConditionallyAddSharedReference(CASR):只在引用计数不为0时才递增。

    在CASR中,ActualOriginalCount 和OriginalCount的比较,是为了再确认ActualOriginalCount != 0。

    ThreadSafe模式的ReleaseShared操作

    当引用计数为0时,执行 DestroyObject()。NoThreadSafe的实现原理一样,代码更简单,就不细说了。

    2,持有关系

    类的持有关系

    3,实现原理

    将Object转换成TSharedRef,可以用如下方法实现

    StaticCastSharedRef实现

    当转换成TSharedRef时,通过如下的构造函数实现引用计数增加(SharedReferenceCount ++):

    FSharedReferencer的引用构成函数 TOps的Add实现

    而TSharedPtr就简单一些,在初始化时,调用EnableSharedFromThis:

    EnableSharedFromThis

    再调用UpdateWeakReferenceInternal,达到弱引用增加(WeakReferenceCount++)

    UpdateWeakReferenceInternal

    这个类的整体实现大体就分析完毕了,这里面还有很多有意思的技巧。例如下面一个好玩的东西,源码如下:

    Source\Runtime\Core\Public\Templates\PointerIsConvertibleFromTo.h部分源码

    这个是做什么东西的?看注释的意思是,测试From* 是不是能转成 To* ,里面的实现很取巧,我写了个测试用例,在这个例子中能比较明显的看出它的用处,代码如下:

    测试代码

    输出

    这个实现还是值得借鉴的。

    这里面的应用是这样的:

    Source\Runtime\Core\Public\Templates\SharedPointer.h部分源码

    TPointerIsConvertibleFromTo 判断 OtherType* 能不能转成 ObjectType* ,如果能,那返回void,TEnableIf的实现如下:

    Source\Runtime\Core\Public\Templates\EnableIf.h的部分源码

    如果Predicate = true 时,Type就存在,否则Type就会成为未定义,那最外层的<...>::Type就会报错。那总结一下,这里的实现了一个在编译时检查OtherType* 是否能转换成ObjectType*的方法,如果不能,那就报错!

    相关文章

      网友评论

        本文标题:Unreal源码阅读(8)SharedPointer

        本文链接:https://www.haomeiwen.com/subject/clfssctx.html