2011-04-07 75 views
2

這種方法不安全嗎?安全std :: tr1 :: shared_ptr的用法

#include <tr1/memory> 

Foo * createFoo() 
{ 
    return new Foo(5); 
} 

int main() 
{ 
    std::tr1::shared_ptr<Foo> bar(create()); 

    return 0; 
} 

或者這將是最好的createFoo返回一個shared_ptr<Foo>對象?

回答

2

這個例子很安全:如果shared_ptr構造函數拋出一個異常,那麼delete是拋出前的指針參數(標準草案,20.9.11.2.1)。

是否create應返回shared_ptr取決於客戶可能合理想要處理的結果。如果他們所做的只是將其包裝在shared_ptr中,那麼請返回以獲得額外的安全。 (是的,shared_ptr可能會引入一些耦合。)

3

您的示例在寫入它的方式上很安全。但是,通過使工廠方法createFoo()返回一個自動指針而不是原始指針,可以使其更加防漏。這樣你就可以保證不會有泄漏。

那麼你得到的是:

#include <memory> 
#include <tr1/memory> 

std::auto_ptr<Foo> createFoo() 
{ 
    return std::auto_ptr<Foo>(new Foo(5)); 
} 

int main() 
{ 
    std::tr1::shared_ptr<Foo> bar(createFoo()); 

    return 0; 
} 

當然,也有可能讓你的工廠方法返回一個shared_ptr,但是這可能會被視爲矯枉過正,因爲返回的指針通常會走出去範圍相當快,因爲​​它將用於賦值或構造函數中。此外,使用auto_ptr更清楚地表明指針的預期用途,當不熟悉代碼的人必須理解它時,這總是一個加號。

+0

爲什麼更密封?如果新Foo(5)失敗,它會破壞所有構造並釋放內存。指針的返回不會失敗,一旦它在'shared_ptr'中就沒有問題。 – 2011-04-07 21:30:59

+0

最好不要使用auto_ptr。在這種情況下,返回一個簡單的指針將會很好。我同意大衛。 – xis 2011-04-07 21:38:20

+2

使用簡單的指針版本,可以執行''Foo * p = createFoo(); p = createFoo();''。如果您不總是將返回的指針從工廠方法分配給智能指針,那麼您可以使用auto_ptr解決方案泄漏內存,這是不可能的。 – Darhuuk 2011-04-07 21:41:11