C++使用#pragma once/头文件保护仍报多重定义错误如何解决?
问题原因
#pragma once以及传统的头文件包含守卫,作用仅为避免单个编译单元内重复引入同一个头文件,无法解决跨编译单元的符号重复定义问题- 你将
some_function()的完整实现直接写在了common.hpp中,而common.hpp被main.cpp、Thing.cpp两个独立的编译单元同时引入,编译后两个目标文件中都会存在some_function()的符号定义,链接阶段就会抛出多重定义的错误。
解决方案
以下任选一种即可:
- 拆分声明与实现(最推荐)
将函数的实现移到单独的源文件中,头文件仅保留声明:
- 修改
common.hpp,仅保留函数声明:
#pragma once void some_function();
- 新建
common.cpp存放实现:
#include "common.hpp" #include <iostream> void some_function() { std::cout << "something" << std::endl; }
- 编译时加入新增的源文件:
g++ main.cpp Thing.cpp common.cpp -o main.out
- 添加inline修饰
如果函数逻辑简单、体积小,可以直接给头文件中的函数添加inline关键字,C++标准允许inline函数在多个编译单元存在相同定义,链接时会自动合并为一份:
#pragma once #include <iostream> inline void some_function() { std::cout << "something" << std::endl; }
- 添加static修饰/放入匿名命名空间
给函数添加static关键字,或者将函数包裹在匿名命名空间中,这样每个引入头文件的编译单元会生成独立的函数实例,不会产生符号冲突。缺点是会生成多份重复的函数代码,仅适合极小的函数使用:
// 加static的写法 #pragma once #include <iostream> static void some_function() { std::cout << "something" << std::endl; }
内容的提问来源于stack exchange,提问作者the2nake
相关产品推荐
相关产品推荐

