2013-09-25 65 views
4

我讀過很多關於前向聲明的文章,但我仍然有一個問題。 讓我們假設有:C++前向聲明和文件設計

// File a.hpp (in this question I avoid writing guards in header files, for the sake of simplicity) 

class A 
{ 
    // Class B is used only by pointer, the compiler doesn't need to know the structure 
    // of the class, so a forward declaration is enough 
    public: 
     A(void); 
     void Method1(B *pB); 
     void Method2(B *pB);   
}; 

// File a.cpp 

#include "a.hpp" 

A::A(void) { } 

// Some methods of class B are used, so the compiler needs to know the declaration of the class, it cannot be forward declared 

void A::Method1(B *pB) 
{ 
    // Something... 
    pB->SomeMethod(); 
    // Something ... 
} 

void A::Method2(B *pB) 
{ 
    int var = pB->GetSomeMember(); 
    // Something ... 
} 

好了,現在讓我們假設有B類聲明一個頭文件,另一個用於其向前聲明:

// File b.hpp 

// Class declaration 
class B 
{ 
/* ... */ 
}; 

// File b_fwd.hpp 

// Forward declaration 
class B; 

我心目中,立足以前的考慮是在a.hpp(它只需要B類的前向聲明)中包含「b_fwd.hpp」,並在a.cpp文件(需要聲明)中包含「b.hpp」,如下所示: :

// File a.hpp 

#include "b_fwd.hpp" // Forward declaration of class B 

class A 
{ 
    public: 
     A(void); 
     void Method1(B *pB); 
     void Method2(B *pB);   
}; 

// File a.cpp 

#include "a.hpp" 
#include "b.hpp" // Declaration of class B 

A::A(void) { } 

void A::Method1(B *pB) { /* like before ... */ } 

void A::Method2(B *pB) { /* like before ... */ } 

我知道這是有效的,但是由於在A班中,我包括了(比方說)「B」兩次,第一次前進聲明,第二次「正常」,這聽起來有點奇怪。我想知道這是否是一種好的做法,以及是否可以在項目中完成。

+2

爲什麼不直接在'a.hpp'中聲明'class B'?你認爲把它放在一個單獨的頭文件中實現了什麼?請注意,'#include「some_file」'指令基本上使預處理器在編譯階段之前複製具有指令的文件中'some_file'的內容。 – JBL

+1

我知道,但我更願意將它「封裝」到.hpp文件中。例如,如果有名稱空間或模板,我不希望每次寫入它們都有可能做出未來更改的錯誤和問題,但我只在.hpp文件中寫過一次。 – yuko

回答

4

我經常用這種技術取得巨大成功。

並回答「爲什麼不只是向前宣佈呢?」這個問題。有時很難轉發聲明。例如,如果某個類是模板類,則前向聲明必須包含模板參數以及類名。

+0

嗯,我懷疑這是否有用!我會遵循JBL的建議。至少當用戶需要使用該類時,他應該熟悉提供的所有模板參數,並且應該能夠編寫適當的前向類聲明。 –

+2

如果您打算使用它,那麼確定您應該知道細節,通過包含該類的主頭文件來獲得這些細節。如果您打算將引​​用或指針作爲參數傳遞給參數,那麼將模板參數複製到多個其他頭文件中是一個維護噩夢。 –

+0

_'Maintenance'_這是一個說法,是的! –