我有这个IGlobal.h文件:
#ifndef _IGLOBALS_
#define _IGLOBALS_
#define _USE_MATH_DEFINES
#define PLUG_NUM_CHANNELS 2
#define PLUG_NUM_PRESETS 1
#define PLUG_FPS 100
#define PLUG_PPQ 96
#define KNOB_NUM_FRAMES 128
#define PIANOROLL_MIN_NOTES 2
#define PIANOROLL_MAX_NOTES 8
#define PIANOROLL_MIN_VELOCITY 40
#define PIANOROLL_MAX_VELOCITY 127
#define PIANOROLL_PATTERN_LENGTH PLUG_PPQ * 4
#define LFO_NUM_SAMPLES 882
#define WAVEPLAYER_WIDTH 441
#define WAVEPLAYER_HEIGHT 136
#define WAVEPLAYER_PATH_LENGTH 256
#define ENVELOPE_MIN_VALUE 0.0001
#include <algorithm>
#include <random>
#include <chrono>
#include <math.h>
#include <cmath>
#include "IPlug_include_in_plug_hdr.h"
using namespace std;
// bitmaps
IBitmap gBitmapKnobGeneral;
#endif // !_IGLOBALS_
我经常在项目中包含.h / .cpp文件。 IBitmap
是一个结构。
当我构建(编译)时,它说:
LNK1169 one or more multiply defined symbols found
LNK2005 "struct IBitmap gBitmapKnobGeneral" ?gBitmapKnobGeneral@@3UIBitmap@@A) already defined in ICustomControls.obj
事实上,每次我加入IGlobal.h时都会有。 #ifndef不应该丢弃这个问题吗?或者编译器只为declarations
而不是definitions
自动执行此操作?
答案 0 :(得分:2)
回答问题#ifndef适用于整个文件。
问题是当你写IBitmap gBitmapKnobGeneral时;您将在包含标头的每个源文件中创建一个实例。 我假设你要做的是创建一个单一的全局实例。 在这种情况下,你会想写。
extern IBitmap gBitmapKnobGeneral;
在IGlobal.h文件中然后在你的一个源文件中创建一个实例,例如IGlobal.cpp
IBitmap gBitmapKnobGeneral;
答案 1 :(得分:0)
在C ++头文件中没有编译,它们被粘贴&#34;到源(cpp)文件。每个源文件都维护着自己独立的#defines集 - 如果你把它放在一个cpp文件中
#define A 1
这又是另一个
#ifndef A
#error A is not defined
#endif
您收到错误&#34; A未定义&#34;。在你的情况下,包含标题IGlobal.h的每个源文件都会通过你的标题一次(#ifdef后卫防止它多次解析)并定义IBitmap gBitmapKnobGeneral;
你的程序最终会有多个变量定义。要了解如何解决问题,请参阅其他答案和评论。
答案 2 :(得分:-1)
#ifndef
检查标识符是否先前已定义,如果没有,则会包含#ifndef
与相应#endif/#else
之间的代码。
如果您之前定义了此标识符,则预处理后代码将不存在,因此我将检查问题是否包含在IGlobal.h中包含的文件或符号中的某个位置 - 可能是其中一个“常量”(例如PLUG_NUM_CHANNELS)也在其他地方。
编辑:
看看#pragma once
- 在我看来,这是一个更清晰的解决方案,它可以为标识符省去很多麻烦。