3

我知道预处理器命令是头文件的重要组成部分,以防止多次定义变量和类。

我一直遇到我的变量被多次定义的问题——即使是预处理器包装器也是如此。这是一个遇到编译器错误的示例项目:

标题:

// TestInclude.h
#ifndef TESTINCLUDE_H_
#define TESTINCLUDE_H_

int myInt;

#endif /*TESTINCLUDE_H_*/

C++:

// TestInclude.cpp
#include <iostream>
#include "IncludeMe.h"
#include "TestInclude.h"

int main( int argc, char* args[] )
{
    std::cin >> myInt;

    IncludeMe thisClass;

    std::cin >> myInt;
}

标题:

// IncludeMe.h
#ifndef INCLUDEME_H_
#define INCLUDEME_H_

class IncludeMe
{
private:
    int privateInt;
public:
    IncludeMe();
};

#endif /*INCLUDEME_H_*/

C++:

// IncludeMe.cpp
#include <iostream>
#include "IncludeMe.h"
#include "TestInclude.h"

IncludeMe::IncludeMe()
{
    std::cout << "myInt: " << myInt;
}

然后我像这样编译:

生成文件:

all:
g++ -g -o TestInclude TestInclude.cpp IncludeMe.cpp

我收到以下错误:

/tmp/ccrcNqqO.o:在函数“IncludeMe”中:/ home/quakkels/Projects/c++/
TestInclude/IncludeMe.cpp:6:“myInt”的多个定义
/tmp/ccgo6dVT.o:/home/quakkels/Projects/ c++/TestInclude/TestInclude.cpp:7: 首先定义在这里
collect2: ld 返回1 退出状态
make: *** [all] Error 1

当我在头文件中使用预处理器条件时,为什么会出现此错误?

4

2 回答 2

9

包含守卫不能防止多重定义。它们只防止无限递归包含。(您当然可以在多个翻译单元中包含相同的标题!)

您永远不应该在标题中包含对象定义*;只有声明

标头.hpp:

extern int a;

文件.cpp:

#include "header.hpp"

int a = 12;

*) 您可以在头文件中包含类定义,以及inline函数和类成员函数。

于 2012-11-08T04:06:00.203 回答
2

您应该extern int myInt;在头文件中使用,并且只int myInt;在要定义它的单个 .cpp 文件中写入。

一些项目使用诸如“IN_FOO_CPP”之类的预处理器宏来通过#ifdefs 自动执行此操作。

于 2012-11-08T04:05:16.160 回答