2010-09-01 75 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. 
相关问题