所以我在头文件中有一个嵌套的命名空间。在命名空间内我有一些独立的数据。但是在编译时,我得到了一个"已经在< ..> .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。
感谢任何帮助。
答案 0 :(得分:2)
您的整数常量具有内部链接,因为它们被声明为const
。因此,即使将此头文件包含在多个翻译单元中,它们也不会产生多个定义错误。
您的字符串指针具有外部链接,因为它们不声明为const
。因此,当此头文件包含在多个翻译单元中时,最终会出现多个定义错误。在程序中,不允许对具有外部链接的对象进行多个非内联定义。
如果您希望字符串指针为const
,就像您的整数一样,您应该将它们声明为
const char *const text = "whatever";
注意额外的const
放在声明中的位置。
但如果你的指针是可修改的全局变量,那么它就是另一回事了。在C ++ 17编译器中,只需添加inline
inline const char *text = "whatever";
在C ++之前的版本17中,你必须在头文件中跳过更复杂的箍与extern
声明的组合。 (在这里搜索关于全局变量的主题 - 它在SO上有很好的涵盖。)
P.S。包含保护与避免链接器错误无关。
答案 1 :(得分:1)
有人发布了帮助我的正确答案,但我认为他们删除了帖子。
简单的答案是使用extern
。
在我的标题文件中:
#ifndef HEADER_H
#define HEADER_H
namespace sod {
namespace e {
extern const int _2D;
extern const int _3D;
extern const int _CUSTOM;
extern const char *text1;
extern const char *text2;
};
};
在cpp文件中:
#include "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";
const char *text2 = "I AM ALSO A C STRING";
};
};