c++ - 已在 .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。
任何帮助表示赞赏。
解决方案
您的整数常量具有内部链接,因为它们是声明的const
。特别是正因为如此,即使此头文件包含在多个翻译单元中,它们也不会产生多个定义错误。
您的字符串指针具有外部链接,因为它们未声明const
。因此,当此头文件包含在多个翻译单元中时,您最终会遇到多个定义错误。在程序中,不允许有多个具有外部链接的对象的非内联定义。
如果您希望您的字符串指针是const
,就像您的整数一样,您应该将它们声明为
const char *const text = "whatever";
注意额外const
的放在声明中的位置。
但是,如果您希望您的指针是可修改的全局变量,那么情况就不同了。在 C++17 编译器中,您可以通过简单地添加inline
inline const char *text = "whatever";
在 C++17 之前的版本中,您必须跳过更复杂的箍与extern
头文件中的声明的组合。(在此处搜索有关全局变量的主题 - SO 对此进行了很好的介绍。)
PS Include 守卫与避免链接器错误无关。
推荐阅读
- firebase - 从 Firebase 获取数据到 react-native 应用程序
- apache-spark - Azure Cosmos(MongoDB API) - 来自 Spark 的错误
- javascript - Socket.io + node.js - 客户端不接收广播发射
- mysql - MySQL - 检查不存在的记录
- c# - 使用 Amazon SES 发送电子邮件 - 使用用户电子邮件
- android - 从 Firebase 数据库检索数据到可扩展列表视图
- java - 从 HIVE 表中掺杂重复,需要写出丢弃的记录和抓取计数
- python - 列出 Comprehension 和 Generators 以避免在使用条件表达式时两次计算相同的值
- javascript - 满足某些条件时如何获取数组的长度?
- sql - 如何使用行计数器运行更新