2010-09-01 79 views
2

我正在用C++編寫一些東西。我有我要包含一個到另一個在如下因素2類(這些只是頭文件):嘗試在另一個類中使用類時出錯

//Timing.h

#ifndef _Timing_h 
#define _Timing_h 
#include "Agent.h" 

class Timing{ 
    private: 
     typedef struct Message{ 
      Agent* _agent; //i get here a compilation problem 
      double _id; 
     } Message; 
     typedef struct MessageArr{ 
     } MessageArr; 
    public: 
     Timing(); 
     ~Timing(); 
}; 
#endif 

//Agent.h

#ifndef _Agent_h 
#define _Agent_h 
#include <string> 
#include "Timing.h" 
using namespace std; 

class Agent{ 
    public: 
     Agent(string agentName); 
     void SetNextAgent(Agent* nextAgent); 
     Agent* GetNextAgent(); 
     void SendMessage(Agent* toAgent, double id); 
     void RecieveMessage(double val); 
     ~Agent(); 
    private: 
     string _agentName; 
     double _pID; 
     double _mID; 
     Agent* _nextAgent; 
}; 
#endif 

的編譯錯誤是在結構的定義裏面的Timing.h文件:

預期「;」 '*'令牌之前

我在做什麼錯?

回答

4

儘量不包括Timing.h「Agent.h」,但包括不是正參考:

#ifndef _Timing_h 
#define _Timing_h 
class Agent; 

class Timing{ 
    private: 
     typedef struct Message{ 
      Agent* _agent; //I get here a compilation problem 
      double _id; 
     }Message; 

     typedef struct MessageArr{ 
     }MessageArr; 

    public: 
     Timing(); 
     ~Timing(); 
}; 
#endif 

可以包括在timing.cpp文件Agent.h

通過這種方式,您可以刪除循環引用並減少類之間的耦合。 由於您不使用類Agent中的類Timing,您也可以刪除此包含(但這可能是您的縮短示例中的複製錯誤)。


基本上 - 無論何時你需要一個對象的大小或它的一些功能,你必須包含它的頭文件。如果你不需要它(例如,如果你只使用指向這個對象或引用的指針),你不應該。這減少了編譯時間(尤其是對於大型項目)


對於1個實例的問題 - 檢查你最喜歡的設計模式書(例如在GoF)。 singleton模式可能是您需要的。

+0

是啊!它確實有幫助, 但是如果我想在Agent.h文件中創建一些Timing.h函數呢? 我需要在Timing.h中包含Agent.h嗎? – 2010-09-01 12:53:11

+0

你能解釋爲什麼這解決了這個問題嗎? – 2010-09-01 12:54:51

+2

因爲當你所做的全部工作是使用一個類作爲返回類型,一個指針或引用成員,或一個指針或引用參數時,編譯器不需要查看該類的完整定義以便繼續。一個簡單的前瞻性聲明說「有一個具有以下名稱的類」就足夠了。如果您想實際*使用*給定類型的對象,則需要進行完整的分解。因此,在time.cpp中,實際使用'Message :: _ agent'字段*時,您確實需要包含'Agent'(agent.h)的完整定義。 – 2010-09-01 13:01:48

1

您需要添加的Agent向前聲明Timing.h

// Timing.h 
#ifndef _Timing_h 
#define _Timing_h 

class Agent; // fwd declaration. 

class Timing{ 
    private: 
     typedef struct Message{ 
      Agent* _agent; // without fwd decln Agent type is unknown here. 
// rest all same. 

編輯:

至於建議由別人,你不應該包括在Agent.hTiming.h

+0

-1用於添加前向聲明,同時仍具有include – morechilli 2010-09-01 12:59:56

2

你不能有通告包括。

停止包含「Agent.h」中的「Timing.h」,因爲它不是必需的。

而且,你不需要有「Agent.h」列入「Timing.h」不是,只是用一種正向參考:

class Agent; 

這使得有可能有​​一個指針的東西稱爲Agent

3

經驗法則。

  1. 如果您不需要,請不要在頭文件中包含其他頭文件。
    • 預編譯頭文件是一個明顯的例外。
  2. 如果你的類只依賴於一個指針或引用您不需要頭文件:
    • 使用前向聲明在這種情況下。
  3. 在源文件中只包括你需要做的頭文件它的工作
    • 包括他們最具體到最不具體。
    • 這將防止隱藏依賴的問題。

其他說明:

  • 不要使用下劃線後由國會的信。
    • 這是保留的實施。 see
    • #define _Timing_h
    • 另請注意,傳統上,宏都是大寫字母。
  • 不要把using namespace X;在頭文件
    • 如果你這樣做,你污染,使用頭文件爲大家的命名空間。
      這是一個真正簡單的方法來PO PO其他開發人員現在必須重新考慮他們的代碼,以確保它沒有使用任何一堆新的類/函數/模板突然被解決了,這是不存在的。

那麼試試這個:

Timing.h

#ifndef TIMING_H 
#define TIMING_H 

class Agent; 

class Timing{ 
// STUFF 
}; 
#endif 

Agent.h

#ifndef AGENT_H 
#define AGENT_H 

#include <string> 

class Agent{ 
// STUFF 
}; 
#endif 

Timing.cpp

#include "Timing.h" 
#include "Agent.h" 

// STUFF 

Agent.h

#include "Agent.h" 
using std::string; // Bring as little as possable into the the global namespace. 
        // prefer to prefix all cases with std:: 

// STUFF. 
相關問題