C++ 多重定义结构

Kit*_*ion 2 c++ linker struct header-files object-files

我的标题util.hpp 包含一个简单的结构:

// util.hpp

struct Point {
  float x;
  float y;
};
Run Code Online (Sandbox Code Playgroud)

两个 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;
  // ...
}
Run Code Online (Sandbox Code Playgroud)
// b.cpp

#include "util.hpp"

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

int main() {
  // ...
}
Run Code Online (Sandbox Code Playgroud)

当我编译a.cppb.cpp独立,然后将它们链接在一起,我没有错误。

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

// util.hpp

struct Point {
  float x;
  float y;
};

// New variable
int foo;
Run Code Online (Sandbox Code Playgroud)

链接时出现以下错误:

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

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

dat*_*olf 5

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

在 C++ 中,您还可以拥有成员函数、运算符以及静态成员变量,但是从技术上讲,这些不是结构/类的一部分,而是结构/类一起提供,因此您只能全局定义它们一次。

就像foo您在那里的全局变量定义一样,如果在包含多次的文件中完成此操作,则不起作用。但您可以安全地多次声明它们。


bru*_*uno 5

bo:(.bss+0x0): `foo' 的多重定义

// util.hpp
...
// New variable
int foo;
Run Code Online (Sandbox Code Playgroud)

每次包括一次util.hpp定义再次全局变量foo的,产生的误差

在头文件中声明它 ( extern int foo;) 并在一个源文件中定义它

struct Point没有同样的问题,因为这是一个类型定义,而不是一个全局变量定义