1

可能重复:
为什么这不能阻止多个函数声明?

全球.h

#ifndef Global_h
#define Global_h

#include <iostream>

unsigned char exitStatus;

#endif

输出处理程序.h

#ifndef OutputHandler_h
#define OutputHandler_h

#include "Global.h"

class OutputHandler {
private:
    static bool instanceExists;
// more code  

#endif

根目录

#ifndef Root_h
#define Root_h

// declarations

OutputHandler *output;

#endif

根.cpp

#include "Root.h"
// gets instance of OutputHandler
// more code

我收到有关exitStatusstatic bool instanceExists静态类输出已由OutputHandler.obj中的Root.obj定义的错误。我认为问题在于将头文件OutputHandler.h 包含Root.hOutputHandler.cpp中。任何人都知道如何解决这个问题或如何更好地组织头文件?

4

3 回答 3

4

因为包含保护仅在翻译单元级别起作用(对于这种简单的情况,您可以将单个 C 文件视为一个翻译单元)。

这意味着单个 C 文件,如果它包含两次头文件,由于包含保护,将不会第二次处理它。

但是,如果您包含来自两个不同C 文件的标头,则它们中的一个都将获得该标头中定义的变量的副本。

然后,当您将它们链接在一起时,您会得到重复项。

解决这个问题的最简单方法是永远不要在标题中定义东西,只声明它们。

因此,在标题(例如xyzzy.h)中,您有:

extern int xyzzy;  // declare but don't define.

在所有想要使用它的 C 文件中,输入:

$include "xyzzy.h"

并且,在其中一个C 文件中,还输入:

int xyzzy;        // define it here, once.

您可以将声明视为简单的“我声明它存在于某个地方,只是不在这里”,而定义是“我在这里和现在创建它”。

于 2013-02-01T09:26:31.663 回答
2

extern usigned char exitStatus一个实现文件中声明Global.h并定义它。

于 2013-02-01T09:26:00.237 回答
1

问题出在链接阶段;在标题中包含警卫对您没有帮助。

在 C 中,声明定义是分开的概念。声明是放在标题中的;他们只是声明存在一个特定的变量。变量的定义是实际为其分配存储的位置。

例如,在您的 中Global.h,您有:

#ifndef Global_h
#define Global_h

#include <iostream>

usigned char exitStatus;

#endif

这是定义一个名为 的变量exitStatus,链接器抱怨,因为任何给定的变量都应该只在程序中的一个地方定义。您需要做的是在标头中声明它,然后在源 (*.cpp) 文件中仅在一处定义它。例如,您的标头应声明exitStatus:

extern char exitStatus;

并且只在一个源文件中定义它:

char exitStatus;

outputin的情况与Root.h您应该在头文件中声明变量的任何其他位置类似。

另见:http ://www.cprogramming.com/declare_vs_define.html

于 2013-02-01T09:28:42.827 回答