template<typename T> class PassRefPtr template<typename T> class RefPtr 構(gòu)造函數(shù): ALWAYS_INLINE RefPtr() : m_ptr(0) { } ALWAYS_INLINE RefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); } template<typename U> RefPtr(const PassRefPtr<U>&, EnsurePtrConvertibleArgDecl(U, T));
拷貝構(gòu)造函數(shù): ALWAYS_INLINE RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { refIfNotNull(m_ptr); } template<typename U> RefPtr(const RefPtr<U>& o, EnsurePtrConvertibleArgDecl(U, T)) : m_ptr(o.get()) { refIfNotNull(m_ptr); }
提供接口:
引用計(jì)數(shù)的實(shí)現(xiàn),就是ref() and deref(),提供兩種方法: 所有的Node類以及子類的ref()實(shí)現(xiàn)(也就是引用計(jì)數(shù)實(shí)現(xiàn))都來源Node繼承于public TreeShared<Node> 。 template<typename NodeType> class TreeShared 這個(gè)類使用要求好像比較高,要求是在主線程中使用。其他和RefCountedBase一樣存在一個(gè)變量 m_adoptionIsRequired。這個(gè)屬性也就是說該對(duì)象創(chuàng)建了并且有多處在共享使用它了 另外在WTF中還有一個(gè)導(dǎo)出類,也是用于實(shí)現(xiàn)引用計(jì)數(shù)的(ref()),采用的是非模板的形式來實(shí)現(xiàn)的。 // This base class holds the non-template methods and attributes. // The RefCounted class inherits from it reducing the template bloat // generated by the compiler (technique called template hoisting). class WTF_EXPORT RefCountedBase 在這個(gè)類的實(shí)現(xiàn)中基本原來都是用一個(gè)變量來記錄一個(gè)對(duì)象的應(yīng)用次數(shù),值得注意的是里面還有三個(gè)成員變量,總體來講這三個(gè)成員變量用于控制其生命周期的: bool m_deletionHasBegun:檢測(cè)是否已經(jīng)開始析構(gòu)對(duì)象 bool m_adoptionIsRequired: ThreadRestrictionVerifier m_verifier:這個(gè)主要是防止在多線程之間共享帶來問題
總結(jié): PassRefPtr 和 RefPtr 實(shí)際都是對(duì)指針的分裝,提供一些接口。RefPtr更多的是用于作為成員變量和局部變量使用。而PassRefPtr是作為函數(shù)返回值使用。按照webkit官方的說法,翻譯過來如下: 局部變量和類成員變量:函數(shù)參數(shù)如果一個(gè)函數(shù)不需要這個(gè)指針的所有權(quán),可以直接傳裸指針,說白了只是用一下,用完了不管里面的內(nèi)容。 如果需要擁有所有權(quán),也就是會(huì)改變他的應(yīng)用計(jì)數(shù),那么就要用PassRefPtr傳進(jìn)來。通常的set函數(shù)的參數(shù)。 除非特別簡(jiǎn)單的情況下,否則一般要在函數(shù)開始部分將這個(gè)參數(shù)賦值給一個(gè)RefPtr。 一般對(duì)這個(gè)參數(shù)命名可以采用”prp“為前綴
函數(shù)返回值:如果一個(gè)函數(shù)返回值中對(duì)象的所有權(quán)不發(fā)生轉(zhuǎn)移,那么就直接返回裸指針.常見于getter函數(shù). 如果一個(gè)函數(shù)返回值是new出來的對(duì)象或者所有權(quán)發(fā)生轉(zhuǎn)移,那么就要用PassRefPtr. 根據(jù)上面的原則,一般函數(shù)內(nèi)部產(chǎn)生的變量是RefPtr,所以這個(gè)時(shí)候需要調(diào)用RefPtr的release接口來生成PassRefPtr
新對(duì)象new出來的對(duì)象必須立即傳給RefPtr 對(duì)于RefCounted類型的對(duì)象,通過采用adopted函數(shù)來進(jìn)行賦值個(gè)RefPtr 最佳的實(shí)踐方法是將構(gòu)造函數(shù)私有化,然后通過create函數(shù)返回一個(gè)PassRefPtr賦值給RefPtr
|