C ++结构的多重定义

时间:2019-07-07 13:20:49

标签: c++ struct linker header-files object-files

我有一个包含简单结构的标头util.hpp

// util.hpp

struct Point {
  float x;
  float y;
};

两个cpp文件,我们称它们为a.cppb.cpp,它们都包含util.hpp

// a.cpp

#include "util.hpp"

void funcA(float _x, float _y) {
  Point p;
  p.x = _x;
  p.y = _y;
  // ...
}
// b.cpp

#include "util.hpp"

void funcB(float _x, float _y) {
  Point p;
  p.x = _x;
  p.y = _y;
  // ...
}

int main() {
  // ...
}

当我分别编译a.cppb.cpp并将它们链接在一起时,没有错误。

那是为什么?由于我在两个文件中都包含util.hpp,所以我们不会有struct Point的双重定义吗? 例如,当我像这样向util.hpp添加变量定义时:

// util.hpp

struct Point {
  float x;
  float y;
};

// New variable
int foo;

链接时出现以下错误:

g++ a.o b.o -o test -O0
b.o:(.bss+0x0): multiple definition of `foo'
a.o:(.bss+0x0): first defined here

这对我来说很有意义,但为什么结构不会出现相同的错误?

2 个答案:

答案 0 :(得分:4)

  

b.o :(。bss + 0x0):'foo'的多个定义

拥有

// util.hpp
...
// New variable
int foo;

每次您包含 util.hpp 时,您再次定义全局变量foo,从而产生错误

只需在头文件中声明extern int foo;)并将其定义在一个源文件中

结构点没有相同的问题,因为这是类型定义,而不是全局变量定义

答案 1 :(得分:3)

类型定义(structunionclassenum)只是编译器如何在内存中布置某些内容的“蓝图”但不要自行生成代码或符号。

在C ++中,您还可以具有成员函数和运算符以及静态成员变量,但是从技术上讲,它们不是struct / class的组成部分,而是带有< / em> struct / class,因此您只能全局定义一次。

就像foo的全局变量定义一样,如果在包含多次的文件中完成,则此定义将无效。但是您可以安全地多次声明