我使用两个相互依赖的类。但是,当我编译程序时,我得到一个荒谬的异常描述。只有在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
会强调包含和悬停显示:"包含文件..包含自身"。这在我的大项目中并没有发生。但是,注释include,取消注释另一个类的实例化,然后编译项目会产生相同的错误。
答案 0 :(得分:1)
问题是编译器在看到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
而不是使用倒数包含。 e.g:
#ifndef __CREATURE_H
#define __CREATURE_H
class World; // instead of #include "World.h"
class Creature
{
public:
World *world;
};
#endif
根据您显示的代码,您可以在world.h中使用Creature
执行相同的操作(尽管您只需要其中一个来解决编译问题)。
答案 1 :(得分:0)
使用前瞻声明。
在Creature.h中更改
#include "World.h"
到
class World;
答案 2 :(得分:0)
我认为这是一个声明问题。在你的头文件中加上“#include”并不是一个好主意。
更好的方法:(注意我使用“#pragma once”而不是“#ifndef #define”)
Creature.h
#pragma once
class World;
class Creature {.........}
World.h
#pragma once
class Creature;
class World {..........}
你的任何.cpp文件
#include "World.h"
#include "Creature.h"
答案 3 :(得分:0)
我建议将预处理器输出发送到文件,并检查实际预处理代码的样子。
要解决这样的问题,我会创建另一个带有前向声明的头文件(例如declarations.h
),然后在定义类实现的每个头中包含前向声明。
保持标题不被包含多次(#ifndef
,#pragma once
等)的常规方法可以完美地工作,以防止任何事情被多次声明或定义,同时允许两个世界和生物用指针互相引用。
这里的关键是,定义main
函数的cpp文件需要包括World.h
和Creature.h