C ++包括看守似乎没有工作

时间:2011-11-12 22:32:55

标签: c++ include

我从mbed C ++编译器收到的错误消息似乎表明包括警卫在内的故障。

在main.cpp中,我按如下方式包含我的头文件:

#include "mbed.h"
#include "sample.h"

这是我的sample.h:

#include "mbed.h"

#ifndef STUFF_H
#define STUFF_H

/* LEDs */
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);

/* Subroutines */
void sweepLEDs();
void pulseLEDs(int numPulses);
void clearLEDs();

#endif

在sample.cpp中,我包括sample.h,如下所示:

#include "sample.h"

在main.cpp和sample.cpp中,我指的是变量led1, led2, led3, led4而没有声明它们。但是,编译器正在输出这些抱怨:

  

“符号led1多重定义(通过sample.cpp.cpp.LPC1768.o和main.cpp.cpp.LPC1768.o)。”   ...   “符号led4多重定义(通过sample.cpp.cpp.LPC1768.o和main.cpp.cpp.LPC1768.o)。”

我的包含警卫是否写得不正确?还是有其他问题吗?

(供参考,这里是link to the mbed.h source

2 个答案:

答案 0 :(得分:12)

问题在于对包括警卫在内的内容的误解。包含防护可防止编译器在同一翻译单元中再次看到相同的内容(对于相同的.cpp文件)。他们阻止单独的翻译单位看到相同的代码。

在头文件中,您定义(而不仅仅是声明)变量。因此,包含标题的每个翻译单元都会创建自己的变量副本。

正确的方法是在.cpp文件中定义变量,并且只在标题中声明它们(无论如何都应该包含防护,以防止多次包含在同一个翻译单元中)。

也就是说,在你的文件sample.h中,用extern为变量添加前缀并删除初始化程序(因此它们只是声明,未定义),并在相应的.cpp文件中定义它们。通过在标题中输入确切的定义来定义函数。

在一个不相关的注释中,你应该将#include "mbed.h"放在include.h中的sample.h中,因为有些编译器可以优化这些防护的编译速度,并且如果包含防护之外的材料,则优化不起作用。请注意,这不是一个真正的正确性问题(假设mbed.h也受到包含警卫的适当保护),但是编译性能问题。

答案 1 :(得分:4)

您需要将声明标记为“extern”,如下所示:

extern DigitalOut led1;

然后使用您在标题中使用的表达式在sample.cpp中定义它们(即为它们分配存储空间)。