[英]Implementing weak intrusive pointers in C++
弱指針就像智能指針,除了弱指針的引用不會阻止垃圾收集,弱指針必須在使用之前檢查它們的有效性。
在我們的項目(Linderdaum Engine http://www.linderdaum.com )中,我們使用了侵入式指針。 為了避免循環引用和孤立孤島,我們通過以下方式實現了弱入侵指針:
namespace LPtr
{
clPtr<iObject> GetObjectsGraphPtrWrapper( sEnvironment* Env, iObject* Obj, size_t Generation );
};
/// Intrusive weak smart pointer
template <class T> class clWeakPtr
{
public:
/// default constructor
clWeakPtr(): Env( NULL ), FObject( NULL ), FGeneration( 0 ) {}
explicit clWeakPtr( T* Ptr )
: Env( Ptr ? Ptr->Env : NULL )
, FObject( Ptr )
, FGeneration( Ptr ? Ptr->FGeneration : 0 ) {}
explicit clWeakPtr( const clPtr<T>& Ptr )
: Env( Ptr ? Ptr->Env : NULL )
, FObject( Ptr.GetInternalPtr() )
, FGeneration( Ptr ? Ptr->FGeneration : 0 ) {}
clPtr<T> Lock() const
{
clPtr<iObject> P = LPtr::GetObjectsGraphPtrWrapper( Env, FObject, FGeneration );
return P.DynamicCast<T>();
}
private:
sEnvironment* Env;
T* FObject;
size_t FGeneration;
};
GetObjectsGraphPtrWrapper
只是為了前向聲明,大致如下:
LMutex Lock( &FObjectsGraphMutex );
clObjectsGraph::const_iterator i = std::find( Env->ObjectsGraph.begin(), Env->ObjectsGraph.end(), Obj );
if ( i == Env->ObjectsGraph.end() ) return clPtr<iObject>();
bool IsSame = Obj->FGeneration == Generation;
bool IsAlive = Obj->GetReferenceCounter() > 0;
return ( IsSame && IsAlive ) ? clPtr<iObject>( Obj ) : clPtr<iObject>();
Generation
在sEnvironment
的范圍內是全局的,並且每次實例化新對象時都是原子遞增的。
我的問題是:
1)實現像這樣的弱引用是否安全?
2)有沒有什么方法可以優化clWeakPtr::Lock()
?
1)確實看起來很安全,但是圖形的任何修改都會與LPtr::GetObjectsGraphPtrWrapper
爭執
2)讀寫鎖可以幫助,至少你可以並行調用幾個Lock()
你的解決方案的問題在於它擊敗了非侵入式弱指針所帶來的局部性。 根據並發級別,它可能會成為一個問題,因為每次調用Lock()
都會阻止任何對象創建,以及任何其他沒有讀寫鎖定的Lock()
調用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.