2

我知道我在这里一定做错了什么。

排名.h

#ifndef RANK_H
#define RANK_H
namespace mmi {
int chunk;
void rank(int my_rank);
}
#endif

排名.cpp

#include "rank.h"
namespace mmi {
//do something with chunk
}

主文件

#include "rank.h"
int main() {
    mmi::chunk = 1;
}

以及编译的输出;

g++ -g -Wall -std=gnu++11   -c -o main.o main.cpp
g++ -g -Wall -std=gnu++11   -c -o rank.o rank.cpp
mpic++ main.o rank.o  -o main
rank.o:(.bss+0x0): multiple definition of `mmi::chunk'
main.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status
Makefile:12: recipe for target 'main' failed
make: *** [main] Error 1

我的理解是头文件被多次包含。但我希望通过使用#ifndef.

那么,请问这里是怎么回事?

4

2 回答 2

4

线

int chunk;

不仅是声明,也是定义。作为 .hpp 文件的每个 .cpp 文件#include最终都会定义它。

将其更改为

extern int chunk;

然后,确保在 .cpp 文件中定义它。

排名.cpp

#include "rank.h"
namespace mmi {
   int chunk;
  //do something with chunk
}
于 2018-07-20T05:05:24.420 回答
2

在 C++ 中,每个文件(又名翻译单元)都是单独编译的。所以main.cpp的编译完全独立于rank.cpp的编译。一个编译中的#define 不可能影响另一个编译。当您将两个目标文件链接在一起时,定义已经消失。

包含保护的目的是防止在单个编译期间包含一个头文件两次,而不是在多个编译中包含。

于 2018-07-20T05:11:42.873 回答