This question already has answers here:
Why aren't my include guards preventing recursive inclusion and multiple symbol definitions?
                                
                                    (3个答案)
                                
                        
                                5年前关闭。
            
                    
我正在使用两个相互依赖的类。但是,当我编译程序时,我得到了一个荒谬的异常描述。我减少了代码以仅在World.h头文件中包含Creature头文件时显示错误。在有机会实现前向声明或模板之前引发该异常。另外,在我的情况下,预处理器指令不起作用。

生物标头:

#ifndef __CREATURE_H
#define __CREATURE_H
#include "World.h"
    class Creature
    {
    public:
        //World *world; -- This class only needs a pointer to world.
    };
#endif


世界头:

#ifndef WORLD_H
#define WORLD_H
#include "Creature.h"
    class World
    {
    public:
        Creature** world;
    };
#endif


一个驱动程序来完成示例:

#include "World.h"
int main()
{
    World world;
    return 0;
}


Visual Studio 2012的异常消息:

world.h(14): error C2143: syntax error : missing ';' before '*'
world.h(14): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int


在最小的示例中,我注意到Intellisense将在包含内容下划线,并在鼠标悬停时显示:“包含文件..包含自身”。这在我的较大项目中不会发生。但是,注释包含,取消注释另一个类的实例,然后编译项目会产生相同的错误。

最佳答案

问题在于,编译器在看到class Creature之前先“看到” World*,并带有其World。如果我们手动执行#include,这将变得显而易见:

#ifndef WORLD_H
#define WORLD_H

   //#include "Creature.h"
      #ifndef __CREATURE_H
      #define __CREATURE_H
      #include "World.h" // the #ifndef prevents this from expanding into anything interesting
      class Creature
      {
      public:
         World *world; // here's World! Except...it hasn't been declared or defined yet.
      };
      #endif

   // finally we get to class World, but it's too late
   class World
   {
   public:
      Creature** world;
   };
#endif


一个简单的解决方案是前向声明World而不是使用倒数包含。例如。:

#ifndef __CREATURE_H
#define __CREATURE_H
    class World; // instead of #include "World.h"

    class Creature
    {
    public:
        World *world;
    };
#endif


根据显示的代码,您可以在world.h中使用Creature进行相同的操作(尽管您只需要使用两者之一来解决编译问题)。

09-25 16:34
查看更多