2013-04-12 66 views
-1

考慮這個類。班級成員總是作爲一致性的指針?

#pragma once 

#include <memory> 
#include <string> 

class A; 
class B; 

class Test 
{ 
public: 
    Test(); 
    ~Test(); 

private: 
    std::unique_ptr<A> m_a; 
    std::unique_ptr<B> m_b; 
    std::unique_ptr<std::string> m_string1; // 1 
    std::string m_string2; // 2 
}; 

我總是嘗試在頭文件中轉發聲明類。但是,我不會那樣做標準頭文件,向前聲明模板類的typedef只是很痛苦。無論如何,如果我有標題可用 - 我應該更喜歡第一種方式還是第二種方式 - m_string1m_string2?我覺得如果我混合使用指針和值類型,那麼它看起來不一致。把所有東西都作爲指針是一個好主意嗎?

+0

此問題屬於http://www.codereview.stackexchange.com/。 – antonijn

+0

我認爲使用指向每個成員的指針可能會導致額外的空間 - 指針在64位系統中需要32位和8字節中的4個字節。簡單的數據類型可以更好地存儲爲值。 – cppcoder

+0

@cppcoder:它可能是對齊使短類型被存儲到相同的長空間......很難說何時(而不是)這是真的。 –

回答

1

std::string已經擁有了一個動態結構(所以它本身是一個指針)

畢竟,如果你考慮一個字符串「不透明類型」這樣不透明的,你甚至不想包含它的頭,同樣的應該也是unique_ptr ...但是你必須遲早停止,否則你最終會得到一類普通的指針,而大五(ctor,dtor,copy,assign,move,transfer)都是重新定義的。但是這是每次都重新實現智能指針。

另外考慮到將一個類拆分成過小的動態「細節」會將對象擴展到內存中,從而不能根據系統緩存對任何處理器進行優化(或使其更難)。

如果你有一些模板,那麼pimpl成語甚至變得毫無用處:你必須將整個類作爲頭部公開。

在我看來,你只是太深入這個成語的應用。

0

你想讓它分配在堆上還是堆棧中?有理由使用每種方法(例如對象的生命週期),爲情況使用適當的選擇。如果你不需要,我覺得指針管理沒有意義;即使你使用智能指針。

此外,像std::string這樣的類在內部通常是指向堆分配字符串的指針。所以在這種情況下,你會爲​​一個指針做堆分配。堆分配比堆棧分配更昂貴,並且大量非常小的分配將趨向於快速地分割堆空間,使得分配器難以找到相鄰空閒空間的合理大小的塊(比較慢)(a.k.a.較慢)。

國際海事組織,一般性的一致性是好的,但爲了一致性的一致性是僵化和不切實際的。

1

如果你要做到這一點,改用pImpl

class TestImpl; 
class Test 
{ 
public: 
    Test(); 
    ~Test(); 

private: 
    std::unique_ptr<TestImpl> m_; 
}; 

和您的.cpp文件中,創建一個與它的所有數據TestImpl那裏。

這會更好地隱藏您的實現細節,並減少間接性,因爲如果仍然刪除了一個間接步驟,則Test的所有數據現在都是連貫的(成簇的)。