【发布时间】:2011-12-03 00:34:27
【问题描述】:
我有一些代码。该代码有四个文件。一个文件是主文件,另外三个是所有结构(即“游戏”结构、“玩家”结构和“场景”结构)。在游戏结构中,我尝试制作一系列“场景”结构。编译器抱怨说“重新定义 struct 'scene'”。有什么帮助吗?
【问题讨论】:
-
不看代码说不出口。
我有一些代码。该代码有四个文件。一个文件是主文件,另外三个是所有结构(即“游戏”结构、“玩家”结构和“场景”结构)。在游戏结构中,我尝试制作一系列“场景”结构。编译器抱怨说“重新定义 struct 'scene'”。有什么帮助吗?
【问题讨论】:
确保在每个标头中包含标头保护以防止重新包含:
#ifndef GAME_H_INCLUDED
#define GAME_H_INCLUDED
...whatever was in game.h before...
#endif /* GAME_H_INCLUDED */
对于其他每个标题也是如此。
您的一个标头可能包含其他标头之一,这会导致重新定义问题 - 因为缺少标头保护。
一些编译器支持#pragma once 以确保它只包含一次给定的标头。如果您将使用的所有编译器都支持它,您可以使用 pragma 代替所示的可移植且可靠的机制;但是,这样做的风险由您自己承担。
没有标题 - 令人费解(实际上,“担心”可能是一个更好的术语)。不同的文件如何知道不同的结构?
在游戏结构中,我尝试制作一组“场景”结构。编译器抱怨说“重新定义 struct 'scene'”。
听起来你必须做类似的事情:
struct game
{
...
struct scene { ... } *next_scene;
struct scene { ... } list_scenes[24];
...
};
这是不允许的;一旦定义了结构标签,就不能重新定义它。最低修订为:
struct game
{
...
struct scene { ... } *next_scene;
struct scene list_scenes[24];
...
};
推荐的修订版(还有很多与您的组织相关的警告):
struct game
{
...
struct scene { ... };
struct scene *next_scene;
struct scene list_scenes[24];
...
};
但是,如果多个源文件使用相同的结构,那么这些东西真的,真的属于头文件;否则你就违反了敏捷开发信条的两个准则(尽管实际上它们是通用的“良好编程”规则):
如果您的多个源文件包含struct game(或struct scene,或struct player)的定义,那么您就是在重复自己(不好,尤其是当您必须更改定义时,并且有不再有一个地方可以查找struct game(或struct scene,或struct player)的定义。
头文件是控制 C++ 开发复杂性的关键。
如果这仍未确定您的问题,那么将很难猜出您做了什么。您需要显示显示问题的最少代码。复制失败的文件,然后调用新文件minimal.cpp(或任何新名称,带有适当的文件后缀)。现在编辑minimal.cpp。除了在语法上完成命名空间或结构所需的东西之外,在错误之后无情地扔掉所有东西。您可以通过策略性地放置 #if 0 和 #endif 对,或使用全面删除来做到这一点。每次更改后,保存文件,检查是否仍然出现相同的编译错误。如果你用#if 0 / #endif注释掉了代码,那么在编译失败后,删除该代码块(并再次保存,并再次检查编译)。尾随材料通常很容易处理;您只需要几个适当放置的大括号和分号。
之后,您开始消除错误之前的材料。继续下去,直到没有一行代码可以删除而不会在编译过程中丢失错误。
此时,如果测试用例少于 40 行,那么您可以在问题中添加一些内容。在那之前,你的工作还不够好。 (注意,repro 中不需要任何 cmets;没有任何 cmets 就很容易理解。)
这是您追踪任何麻烦的错误的方法 - 尽快消除尽可能多的代码,只留下麻烦的东西。
【讨论】:
gamestruct.h 中的 struct game 应该有一个成员,可能是 int 或其他一些内置类型,因此您不需要其他头文件来编译它;gamestruct.h 总共是三行, 或 6 如果你应该包含标题保护,尽管它们对于重现来说并不重要)。