2009-07-24 51 views
17

在學習C++(和Direct3D,但是前一段時間)時,我一直在困惑的事情之一是何時應該在類中使用指針成員。例如,我可以用一個非指針聲明:C++ - 什麼時候應該在類中使用指針成員

private: 
    SomeClass instance_; 

或者,我可以用一個指針聲明

private: 
    Someclass * instance_ 

然後在構造上它使用新的()。

據我所知,如果SomeClass可以從另一個類派生,一個COM對象或是一個ABC,那麼它應該是一個指針。還有其他的指導方針,我應該知道嗎?

回答

17

指針具有以下優點:

一)你可以做一個懶惰的初始化,這意味着第一次真正使用前給init /創建對象只是短期。 b)設計:如果你爲外部類類型的成員使用指針,你可以在你的類的上面放置一個前向聲明,因此不需要在頭中包含這些類型的頭信息 - 而不是你在你的.cpp中包含了第三方頭文件 - 這有利於減少編譯時間並通過包含太多其他頭文件來防止副作用。

class ExtCamera; // forward declaration to external class type in "ExtCamera.h" 

class MyCamera { 
public: 
    MyCamera() : m_pCamera(0) { } 

    void init(const ExtCamera &cam); 

private: 
    ExtCamera *m_pCamera; // do not use it in inline code inside header! 
}; 

c)一個指針可以在任何時候刪除 - 所以您對livetime更多的控制,且可以重新創建一個對象 - 在出現故障的情況下,例如。

+2

對於惰性初始化,我會建議儘可能使用`boost :: optional`。它比指針更安全,因爲你不能對它進行算術運算。 – 2009-07-24 03:55:12

+1

但許多人(像我)不使用Boost--所以這是一個非常平臺和框架獨立的方式;-) ...我例如只使用Qt :-) – 3DH 2009-07-24 03:59:32

10

如果可以的話,從免費商店分配它,如果必須的話。有一個similar question在這裏,你會發現所有的「爲什麼」。

因爲DirectX是一個COM接口,並且誠實地說,當天大多數遊戲程序員都不是真正的C++程序員,他們是C-與類的程序員,並在C指針的使用是非常普遍的。

17

使用指針的優點通過3DH進行了概述:延遲初始化,減少頭依賴性和控制對象的生命週期。

這也是缺點。當你有一個指針數據成員時,你可能必須編寫自己的拷貝構造函數和賦值操作符,以確保正確創建了該對象的副本。當然,你也必須記得刪除析構函數中的對象。另外,如果您將指針數據成員添加到現有類中,則必須記得更新複製構造函數和運算符=。總之,擁有一個指針數據成員對你來說更有用。

另一個缺點是控制指針指向的對象的生命期的另一個缺點。當對象被銷燬時,非指針數據成員會被自動銷燬,這意味着只要對象存在,就可以確保它們存在。隨着指針,你必須檢查它是否爲nullptr,這意味着你必須確保將它設置爲nullptr,只要它不指向任何東西。必須處理所有這些可能很容易導致錯誤。

最後,訪問非指針成員可能會更快,因爲它們在內存中是連續的。另一方面,訪問指向堆中分配的對象的指針數據成員很可能會導致緩存未命中,從而導致緩慢。

你的問題沒有單一的答案。你必須看看你的設計,並決定指針數據成員的優點是否超過額外的頭痛。如果減少編譯時間和標頭依賴性非常重要,請使用pimpl idiom。如果您的數據成員在某些情況下可能不需要您的對象,請使用指針並在需要時進行分配。如果這聽起來不像是令人信服的理由,並且你不想做額外的工作,那麼不要使用指針。

3

使用指針的另一個原因是動態綁定。如果您有一個帶有虛擬方法和一些派生類的基類,則只能使用指針進行動態綁定。

相關問題