2011-10-27 141 views
2

我發現這個問題When to use forward declaration?這是有用的,但它是描述性的而不是說明性的。C++我應該使用前向聲明嗎?

我的場景通常是使用指向另一個類的指針,作爲類成員或函數參數,因此我只需要在頭文件中提供一個前向聲明(也作爲旁白,如果我要切換到使用boost shared_ptr是否與使用前向聲明兼容?)。目前我只是包括標題,但現在我想知道是否應該使用前向聲明。

所以我的問題是,如果我可以使用一個類的前向聲明,應該我?我希望這個問題不是主觀的,但如果沒有最佳實踐答案,那麼使用前向聲明有什麼優點/缺點?

UPDATE

只是對shared_ptr的問題擴大(我現在不使用他們,但考慮到開關)。如果我要使用它們,我想我會使用在類中定義shared_ptr類型的做法。例如:

class Customer 
{ 
public: 
    typedef std::tr1::shared_ptr<Customer> SharedPointer; 

    Customer() {} 
    virtual ~Customer() {} 

    virtual std::string GetName() const; 
}; 

看起來像這樣可能會使事情變得更加混亂。前向聲明會造成問題嗎?如果有的話,是否有簡單的解決方法?

回答

5

您可能想這樣做,因爲包含這些文件會使編譯時間更長,但取決於您擁有多少個案例以及代碼庫的規模,這很可能不會成爲問題。

要考慮的另一件事是依賴關係。當你需要的只是指針定義時,你不想重新編譯你所有的代碼,因爲你改變了包含文件。

所以我的(主觀)答案是是的,你應該

+2

只是爲了完成答案:是的,'boost :: shared_ptr'正常工作,正向聲明 –

+0

它更快,並避免了問題。是的,肯定更喜歡preclarations包括。 –

1

是的,你應該。請記住,代碼的客戶端使用它時,包含在標題中的任何內容都會包含在內。最好只在頭中包含所需的最少文件數量。除此之外,如果你不需要包含整個文件並且前向聲明足夠,那麼它就像是一個簡單的選擇。

-1

他們通常說你應該儘可能使用前向聲明。像所有規則一樣,這條規則也有例外。對我而言,例外情況往往是類型名稱過於複雜(即模板),或名稱太多時。例如,下面是一個向前聲明:

namespace foo 
{ 
    namespace bar 
    { 
     template <typename T1, typename T2, int X> 
     class MyNiftyType; 
     // Hmm, maybe declare more types here? 
    } 
    // Hmm, maybe declare even more types here? 
} 

如果這些東西能這樣做只是#include "MyNiftyStuff.h"是可以避免的,我最好#include

順便說一句,有一個標準的頭文件<iosfwd>,其中包含一些流類型的前向聲明。它似乎是專門發明的,所以你可以聲明operator<<(std::ostream&, ...)(這是我個人的意見,如果它畢竟是錯誤的,很抱歉)。編號:關於shared_ptr<type>

粗略地說,你可以用共享指針(對前向聲明類型)做的唯一事情就是聲明函數。如果你想定義一個函數來做shared_ptr<type>的一些有用的功能,你不能只向前聲明type。例如:

MyCode.h

class MyClass; 
void DoMuchStuff(shared_ptr<MyClass> ptr); // declaration - OK 
inline void DoDoubleStuff(shared_ptr<MyClass> ptr) // definition - not OK! 
{ 
    void DoMuchStuff(ptr); 
    void DoMuchStuff(ptr); 
} 

如果我用一個正常的指針,而不是shared_ptr,這將與前申報工作。但是這種不便很少碰到你 - 要麼你在.h文件中只有聲明,要麼你的內聯函數足夠複雜,你必須爲你的類完整聲明#include

+2

沒問題,直到你將#include包含在另一個文件中導致問題的東西。如果折衷是更快的編譯和更少的錯誤代碼結構,誰會關心類型名稱是否很長? –

1

我認爲它能夠更好地使用預先聲明,以提高編譯速度(不包括masssive文件) 使用共享指針它並沒有改變任何東西作爲共享指針的問題是隻是一個包裝採取清理堆內存

的護理