弱指针

本页面的内容:

弱指针存储了一个对象的 弱引用 。和共享指针不同,弱指针不会阻止对象被销毁。无论谁销毁了弱指针引用的对象,弱指针都将自动清空。这也意味着,您可能会出乎意外地发现弱指针变为空了,弱指针可以用于断开引用循环。

当不存在到弱指针的对象的共享引用时,将会销毁该对象。

弱指针可以帮助您表明意图。当您在一个类中看到一个弱指针时,您便知道这个类仅是缓存了一个到该对象的指针,并不会控制该对象的生命周期。

声明和初始化

弱指针都是基于共享指针/引用 或 其他的弱指针进行创建的。

// 分配新的树节点
TSharedRef<FTreeNode> NodeOwner( new FTreeNode() );

// 对新的树节点创建弱指针
TWeakPtr<FTreenode> NodeObserver( NodeOwner );

记住,弱指针不会阻止销毁对象。如果重置了NodeOwner但NodeObserver仍在作用范围内,那么将会删除对象:

// 销毁节点
NodeOwner.Reset();

弱指针可以随意地进行安全的复制,就像共享指针一样。

TWeakPtr<FTreeNode> NodeObserverB = NodeObserver;

当您使用完一个弱指针时,您可以重置(或重新分配)它。

NodeObserver = NULL;

解引用和访问

要想访问一个弱指针的对象,首先需要调用 Lock() 方法将其提升为共享指针。

// 通过弱指针来获取对节点的访问
TSharedPtr<TFreeNode> LockedObserver( NodeObserver.Lock() );

If( LockedObserver.IsValid() )
{
    //对象仍存在,因此可以访问它
    LockedObserver->ListChildren();
}

Lock() 函数执行很快。之所以称为Lock(锁定)是因为当临时访问弱指针时它可以阻止对象被销毁。

当弱指针的对象被删除时,它会自动知道,以便您可以通过使用 IsValid() 方法以安全的方式处理这些情况。

//请在访问弱指针的对象前确认其仍然存在
if( NodeObserver.IsValid() )
{
    ...
}

使用弱指针断开引用循环

您可以使用弱指针断开引用循环:

class FTreeNode
{
    /** 子节点,由此节点所有 */
    TArray< TSharedPtr<FTreeNode> > Children;

    /** 返回到此节点父类的弱指针 */
    TWeakPtr<FTreeNode> Parent;
}

FTreeNode 具有共享指针,这些共享指针指向 FTreeNode拥有 的子节点。这将意味着这些子节点将随着它一起销毁。它也使用了一个弱指针,缓存了到其父项节点的引用。弱指针永远不会阻止对象被销毁。通过这样使用共享指针/弱指针,使得权力链更加明显。

当弱指针的对象被删除时,弱指针能“自动知道”,所以您可以这样安全地缓存到树中的任何节点的指针。

转换

您可以使用 Pin() 方法把弱指针转换为共享指针。没有显性的构造函数。