发现无论看到哪里都绕不开这个类,那我们就来看看这个类到底有什么玄机。源码
看注释,就知道它大有来头:

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

引用计数有两个,一个是共享引用计数,一个是弱引用计数。一般的实现是在SharedReferenceCount=0 或者 =1而且引用者是自身时,DestroyObject。上面的源码是ReferenceControllerBase,后面有各种子类的实现。
那它就在什么情况下,count会变化呢?在这里,unreal设计了一个专门的template struct来实现它。

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

AddSharedReference:原子级别的递增。
ConditionallyAddSharedReference(CASR):只在引用计数不为0时才递增。
在CASR中,ActualOriginalCount 和OriginalCount的比较,是为了再确认ActualOriginalCount != 0。

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

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

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


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

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

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

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*的方法,如果不能,那就报错!
网友评论