【问题标题】:constants in header file cause multiple definition errors头文件中的常量导致多个定义错误
【发布时间】:2014-02-28 15:18:52
【问题描述】:

FCORE 宏用于共享库导出。

这是我的头文件 FMath.h

namespace FMath {
    // ...
    FCORE const float PI_32 = 3.14159265359f; // pi
    FCORE inline float  Floor(float value) { return floorf(value); }
namespace FConvert {
    // ...
    FCORE const float DEG_TO_RAD_32 = 0.01745329252f; // pi / 180
    FCORE inline float ToRadian(float degree) { return degree * DEG_TO_RAD_32; }
}
}

我的 FConvert 命名空间中的所有常量值都会导致错误,但不会在 FMath 中声明。我不明白为什么?

FMeshTraits.obj:-1: 错误: LNK2005: DEG_TO_RAD_32 已经定义在 FMesh.obj

编辑:对不起,我没有说我已经使用过这个宏。

#ifndef FMATH_H
#define FMATH_H

// All of the code is here

#endif

【问题讨论】:

  • 你在多个 TU 中定义了同一个变量,所以多个对象都有它。您可以尝试使用静态或匿名命名空间使它们在每个 TU 中唯一,或者仅在一个 TU 中定义它们。
  • 请您解释一下吗?
  • 什么是FCORE?你能展示一下吗?是否包含关键字 extern?
  • 很抱歉我没有看到这个。 FCORE 是来自 Qt 的共享库指令 (Q_SHARED_EXPORT, Q_SHARED_IMPORT)

标签: c++ constants header-files


【解决方案1】:

看起来您有两个 .cpp 文件 FMeshTraits.cpp 和 FMesh.cpp(行话中的两个单独的“翻译单元”)。每一个都被编译成一个单独的 .obj 文件。

下一步是将这些 .obj 文件链接到一个可执行文件中。但是 - 如果一个符号有多个冲突的定义,那么链接器将失败并显示您看到的错误消息。

避免这种情况的常用方法是只在头文件中声明(即声明类型但没有定义),并将所有定义放入 .cpp 文件中。这样一来,您就不会在多个 .obj 文件中拥有相同的定义,因此您不会遇到链接器冲突。

因此,在 FMath.h 中,您将拥有:

FCORE const float DEG_TO_RAD_32;

在 FMath.cpp 中你会得到:

DEG_TO_RAD_32 = 0.01745329252f;

【讨论】:

  • 现在它说“const object must be initialized if not extern”。
  • 这里接受的答案描述了这种情况:stackoverflow.com/questions/2328671/… 基本上 - 如果 FCORE 包含“extern”,那么我编写它的方式应该可以工作(在标题中声明,在一个 .cpp 文件中定义)。如果它不包含 extern 那么您的原始代码应该可以工作(const / inline 应该具有“内部链接”因此不必担心多个定义)
猜你喜欢
  • 1970-01-01
  • 2013-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多