将CDT.h加入stdafx.h预编译头时LNK2005错误的解决方法
解决CDT.h加入预编译头stdafx.h后的LNK2005错误
问题根源
仅头文件库如果包含非inline的函数定义、全局/静态变量定义(不是声明),把它放进预编译头stdafx.h后,所有包含该预编译头的源文件都会生成这些符号的副本,链接阶段就会触发LNK2005重复定义错误。
具体解决步骤
1. 排查CDT.h的重复定义点
打开CDT.h,找以下内容:
- 全局变量定义:比如
int g_cdtVar;(不是带extern的声明) - 非inline函数实现:比如
void cdtFunc() { ... }(没加inline关键字) - 类的静态成员变量定义:类内声明后,类外直接写
Type Class::var = val;(没加inline)
2. 修改CDT.h的问题代码
- 全局变量:把定义改成
extern int g_cdtVar;,然后新建一个CDT_impl.cpp文件,在里面写int g_cdtVar;做实际定义。 - 非inline函数:给函数加上
inline关键字,或者把函数实现移到CDT_impl.cpp里。 - 静态成员变量:C17及以后直接在类内用
inline static Type var = val;定义;C17之前就在CDT_impl.cpp里写Type Class::var = val;。
3. 更新CMake配置
如果新增了CDT_impl.cpp,要在CMakeLists.txt里把它加入编译目标:
add_executable(YourProjectName main.cpp stdafx.cpp CDT_impl.cpp)
4. 清理缓存重新构建
旧的预编译头缓存可能残留问题,清理后重新构建:
# Linux/macOS rm -rf build/ && mkdir build && cd build && cmake .. && make
Windows下直接删除build文件夹,重新生成解决方案即可。
无需修改库源码的临时方案
如果不想动CDT.h的代码,别在stdafx.h里包含它,而是在需要的.cpp文件开头加:
#define CDT_HEADER_ONLY #include "CDT.h"
多数仅头文件库会通过这类宏控制符号生成逻辑,避免重复定义。
内容的提问来源于stack exchange,提问作者PetrasVestartasEPFL
相关产品推荐
相关产品推荐

