2011-08-25 82 views
1

因此,我已經聽到過有關現代C++風格的一個經驗法則,那就是不應該使用new或delete,而應該使用智能指針。所以當我有一個類,其中一個成員是指向另一個對象的指針時,如何去解決這個問題。通過使用智能指針,我可以避免需要刪除,但我仍然需要使用新建對象。例如。是下面的「典型」現代C++風格,還是應該怎麼做呢?在「現代C++」中作爲類成員對象的指針

 

#include 
#include 

class B { 
public: 
    B() { std::printf("constructing B\n");} 
    ~B() { std::printf("destroying B\n");} 
}; 

class A { 
public: 
    A() 
    { 
     std::printf("constructing A\n"); 
     b = std::unique_ptr(new B()); 
    } 
    ~A() { std::printf("destroying A\n");} 

private: 
    std::unique_ptr b; 
}; 

int main() 
{ 
    A a; 
    return 0; 
} 

 
+2

我知道Boost有這個,我假設C++ 0x有類似的東西,但是你可以使用'boost :: make_shared (9)'而不是'boost :: shared_ptr (new int(9))' – Dawson

+2

不要聽那些試圖告訴你這個或那個沒有更多的「現代風格」的人。建議可能是好的或壞的,但是你需要在你正在編寫的特定代碼中爲你自己(和你的繼任者)提供有用的幫助。否則,你只是參加一次貨物崇拜。 –

+0

我認爲你很難建議設計C++程序與RAII相關,因此不需要或很少需要實現顯式析構函數(這也意味着幾乎不需要使用delete來顯式釋放對象)。 – mloskot

回答

7

您使用new。使用new沒有任何問題,它應該儘可能少使用。

(在另一方面delete,應該幾乎從來沒有被使用,因爲它的使用應該始終可以在某種RAII的封裝處理像智能指針或容器)。


注意當使用智能指針時,您應始終將new的結果分配給指定的智能指針或使用reset。在你的情況,你想使用:

A() : b(new B()) { } 

或:

A() 
{ 
    std::unique_ptr<B> x(new B()); 
    b = std::move(x); 
} 

或:

A() { b.reset(new B()); } 

(爲什麼這很重要,請參閱 「最佳實踐」 一節的boost::shared_ptr documentation。)

+0

+1。只要所有新表達式都立即包含在管理對象的構造函數中(單責任原則),就可以在類構造函數內使用'new'。在獨立代碼中,你可以使用'make_shared'來避免'new',但如果你使用'unique_ptr',那麼一個好的'new'就可以。 –