首页 > 解决方案 > 已在 .obj 中定义,即使使用 #ifndef #define #endif

问题描述

所以我在头文件中有一个嵌套的命名空间。在命名空间内,我有一些独立的数据。但是在编译时,我得到一个“已经在 <..>.obj 中定义”。我尝试过使用内联,但显然内联只适用于函数。这是我的代码:

#ifndef HEADER_H
#define HEADER_H

namespace sod {
    namespace e {
        const int _2D = 0;
        const int _3D = 1;
        const int _CUSTOM = 2;
        const char *text1 = "I AM A C STRING";       // <-- char const * const sod::e::text1 (?text1@e@sod@@3PBDB) already defined in main.obj
        const char *text2 = "I AM ALSO A C STRING";  // <-- char const * const sod::e::text2 (?text2@e@sod@@3PBDB) already defined in main.obj
    };
};

#endif

我使用的编辑器是 Visual Studio 2017。

任何帮助表示赞赏。

标签: c++namespaceslinker-errors

解决方案


您的整数常量具有内部链接,因为它们是声明的const。特别是正因为如此,即使此头文件包含在多个翻译单元中,它们也不会产生多个定义错误。

您的字符串指针具有外部链接,因为它们声明const。因此,当此头文件包含在多个翻译单元中时,您最终会遇到多个定义错误。在程序中,不允许有多个具有外部链接的对象的非内联定义。

如果您希望您的字符串指针是const,就像您的整数一样,您应该将它们声明为

const char *const text = "whatever";

注意额外const的放在声明中的位置。

但是,如果您希望您的指针是可修改的全局变量,那么情况就不同了。在 C++17 编译器中,您可以通过简单地添加inline

inline const char *text = "whatever";

在 C++17 之前的版本中,您必须跳过更复杂的箍与extern头文件中的声明的组合。(在此处搜索有关全局变量的主题 - SO 对此进行了很好的介绍。)

PS Include 守卫与避免链接器错误无关。


推荐阅读