IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    SOUI的智能指针赏析

    Enic发表于 2015-05-14 02:07:00
    love 0
    之前自己设计Ref类型遇到new出来的地址,和Ref的this指针一致的情况,soui的这套做法一定程度避免了
    如果有普通的单根继承直接使用: public
    TObjRefImpl
    如果是多根继承可以指定析构类型 :public TObjRefImpl2
    但是多重继承两个Ref类还是没有解决,原则上应该劲量不再非接口是上使用多重继承


    1
    template<class T>
    2 class TObjRefImpl : public T
    3 {
    4 public:
    5 TObjRefImpl():m_cRef(1)
    6 {
    7 }
    8
    9 virtual ~TObjRefImpl(){
    10 }
    11
    12 //!添加引用
    13 /*!
    14 */
    15 virtual long AddRef()
    16 {
    17 return InterlockedIncrement(&m;_cRef);
    18 }
    19
    20 //!释放引用
    21 /*!
    22 */
    23 virtual long Release()
    24 {
    25 long lRet = InterlockedDecrement(&m;_cRef);
    26 if(lRet==0)
    27 {
    28 OnFinalRelease();
    29 }
    30 return lRet;
    31 }
    32
    33 //!释放对象
    34 /*!
    35 */
    36 virtual void OnFinalRelease()
    37 {
    38 delete this;
    39 }
    40 protected:
    41 volatile LONG m_cRef;
    42 };
    43
    44 template<class T,class T2>
    45 class TObjRefImpl2 : public TObjRefImpl
    46 {
    47 public:
    48 virtual void OnFinalRelease()
    49 {
    50 delete static_cast(this);
    51 }
    52 };
    53
    54 //CAutoRefPtr provides the basis for all other smart pointers
    55 template <class T>
    56 class CAutoRefPtr
    57 {
    58 public:
    59 CAutoRefPtr() throw()
    60 {
    61 p = NULL;
    62 }
    63 CAutoRefPtr(_In_ int nNull) throw()
    64 {
    65 (void)nNull;
    66 p = NULL;
    67 }
    68 CAutoRefPtr(_In_opt_ T* lp) throw()
    69 {
    70 p = lp;
    71 if (p != NULL)
    72 {
    73 p->AddRef();
    74 }
    75 }
    76
    77 CAutoRefPtr(const CAutoRefPtr & src) throw()
    78 {
    79 p=src.p;
    80 if(p)
    81 {
    82 p->AddRef();
    83 }
    84 }
    85
    86 ~CAutoRefPtr() throw()
    87 {
    88 if (p)
    89 {
    90 p->Release();
    91 }
    92 }
    93
    94 T* operator->() const throw()
    95 {
    96 return p;
    97 }
    98
    99 operator T*() const throw()
    100 {
    101 return p;
    102 }
    103 T& operator*() const
    104 {
    105 return *p;
    106 }
    107 //The assert on operator& usually indicates a bug. If this is really
    108 //what is needed, however, take the address of the p member explicitly.
    109 T** operator&() throw()
    110 {
    111 SASSERT(p==NULL);
    112 return &p;
    113 }
    114 bool operator!() const throw()
    115 {
    116 return (p == NULL);
    117 }
    118 bool operator<(_In_opt_ T* pT) const throw()
    119 {
    120 return p < pT;
    121 }
    122 bool operator!=(_In_opt_ T* pT) const
    123 {
    124 return !operator==(pT);
    125 }
    126 bool operator==(_In_opt_ T* pT) const throw()
    127 {
    128 return p == pT;
    129 }
    130
    131 T* operator=(_In_opt_ T* lp) throw()
    132 {
    133 if(*this!=lp)
    134 {
    135 if(p)
    136 {
    137 p->Release();
    138 }
    139 p=lp;
    140 if(p)
    141 {
    142 p->AddRef();
    143 }
    144 }
    145 return *this;
    146 }
    147
    148 T* operator=(_In_ const CAutoRefPtr
    & lp) throw()
    149 {
    150 if(*this!=lp)
    151 {
    152 if(p)
    153 {
    154 p->Release();
    155 }
    156 p=lp;
    157 if(p)
    158 {
    159 p->AddRef();
    160 }
    161 }
    162 return *this;
    163 }
    164
    165 // Release the interface and set to NULL
    166 void Release() throw()
    167 {
    168 T* pTemp = p;
    169 if (pTemp)
    170 {
    171 p = NULL;
    172 pTemp->Release();
    173 }
    174 }
    175
    176 // Attach to an existing interface (does not AddRef)
    177 void Attach(_In_opt_ T* p2) throw()
    178 {
    179 if (p)
    180 {
    181 p->Release();
    182 }
    183 p = p2;
    184 }
    185 // Detach the interface (does not Release)
    186 T* Detach() throw()
    187 {
    188 T* pt = p;
    189 p = NULL;
    190 return pt;
    191 }
    192 HRESULT CopyTo(_Deref_out_opt_ T** ppT) throw()
    193 {
    194 if (ppT == NULL)
    195 return E_POINTER;
    196 *ppT = p;
    197 if (p)
    198 {
    199 p->AddRef();
    200 }
    201 return S_OK;
    202 }
    203
    204 protected:
    205 T* p;
    206 };
    struct IObjRef
    {
    virtual long AddRef() = 0;

    virtual long Release() = 0;

    virtual void OnFinalRelease() =0;
    };




    Enic 2015-05-14 10:07 发表评论


沪ICP备19023445号-2号
友情链接