尝试在另一个类中使用类时出错

时间:2010-09-01 12:43:38

标签: c++

我正在用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

编译错误位于struct的定义内的Timing.h文件中:

  

预期';'在'*'标记之前

我做错了什么?

4 个答案:

答案 0 :(得分: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

您可以在Agent.h文件中加入timing.cpp

这样您可以删除循环引用,并减少类之间的耦合。 由于您未在班级Timing中使用班级Agent,因此您也可以删除此包含(但这可能是您缩短示例中的复制错误)。


基本上 - 无论何时需要对象的大小或某些功能,都必须包含其头文件。如果您不需要它(例如,如果您只使用指向此对象或引用的指针),则不应该。这减少了编译时间(特别是对于大型项目)


对于1个实例问题 - 检查您最喜欢的设计模式书(例如GoF)。 singleton模式可能就是您所需要的。

答案 1 :(得分:3)

经验法则。

  1. 如果您不需要,请不要在头文件中包含其他头文件。
    • 预编译的头文件是一个值得注意的例外。
  2. 如果您的类仅依赖于指针或引用,则不需要头文件:
    • 在这种情况下使用前向声明。
  3. 在源文件中仅包含使其工作所需的头文件
    • 将它们从最具体到最不具体包括在内。
    • 这可以防止隐藏依赖项的问题。
  4. 其他说明:

    • 请勿使用Underscore,然后使用国会大厦字母。
      • 这是为实施保留的。 see
      • #define _Timing_h
      • 一样
      • 另请注意,传统上宏都是大写的。
    • 不要将using namespace X;放在头文件中
      • 如果这样做,则会污染使用头文件的每个人的命名空间 对于PO其他开发人员来说,这是一个非常简单的方法,他们现在必须重新考虑他们的代码,以确保它不会使用任何突然被解决的新类/函数/模板中的任何一个。 / LI>

    所以试试这个:

    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.
    

答案 2 :(得分:2)

你不能拥有循环包含。

停止在“Agent.h”中包含“Timing.h”,因为那里不需要它。

此外,您不需要在“Timing.h”中包含“Agent.h”,只需使用前向引用:

class Agent;

这使得可以指向名为Agent的东西。

答案 3 :(得分: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.h

中加入Timing.h