2015年10月28日 星期三

Smart_Ptr 的注意事項

Smart_Ptr 對包裹的對象採取隱性轉型的方式,使用有它的方便性,但也有它的危險性,用一個例子來說:

class A:public cxxlObject;
void f(const Smart_Ptr<A> &A_Arg);

A *pA = new A;
f(pA);

Smart_Ptr<A> 的建構子會隱性的接收 pA,而自動產生 Smart_Ptr<A> 實例傳給 f(),若 f() 的實作並未使用 Smart_Ptr<A> 保存,由 f() 返回時就會把 pA 刪掉。解決的辦法就是儘早先將 pA 先放入 Smart_Ptr:


Smart_Ptr<A> A_Ptr = new A;
f(A_Ptr);

還有...

// A 的成員函數
A::MemF()
{
  f(this);
}

A 物件若沒儘早先放入 Smart_Ptr,後果也一樣。但...

// A 的建構子
A::A()
{
  f(this);
}

這嚴格被禁止。

其實 f() 若不保存,可以宣告成 void f(A &A_Arg),這麼一來呼叫端有沒有先放入 Smart_Ptr,就沒那麼重要,因單一線程式會等 f() 跑完才返回。

但 f() 的實作若是多線程非同步,那麼呼叫端有可能由 f() 返回後,f() 的實作還在另一個線程式上跑,這時 A 的物件若背被 delete 就會出大亂子了,所以 CxxlMan2 程式庫提供的功能函數,不管會不會保留傳來的 cxxlObject 物件,都會用 Smart_Ptr 接收。

沒有留言:

張貼留言