[牛人杂谈] 我发现把函数实体放头文件就会报错,说重复定义,如果只把函数声明放.h头文件,把实...

[复制链接]
1053|1
 楼主| heisexingqisi 发表于 2025-2-17 09:15 | 显示全部楼层 |阅读模式
我发现把函数实体放头文件就会报错,说重复定义,如果只把函数声明放.h头文件,把实体放对应头文件同名的.c文件就没事。
大家遇到过没?
一起讨论一下
该问题是由于C/C++中的**单一定义规则(One Definition Rule, ODR)**引起的。这个规则要求,在同一个编译单元中,函数或变量的定义只能出现一次。

原因分析:
头文件中的函数定义:
如果你在头文件中直接定义了函数实体(即函数的实现),那么当多个源文件(.c或.cpp文件)包含这个头文件时,每个源文件都会包含这个函数的定义。在链接阶段,链接器会发现多个相同的函数定义,从而导致重复定义的错误。

头文件中的函数声明:
如果你只在头文件中声明函数(即函数原型),而在对应的源文件中定义函数实体,那么每个包含该头文件的源文件只会看到函数的声明,而不会看到定义。函数的定义只存在于一个源文件中,因此不会导致重复定义的问题。


解决方法:
将函数声明放在头文件中:
头文件(.h)中只包含函数的声明(原型),例如:

  1. // myheader.h
  2. void myFunction();


将函数定义放在源文件中:
在对应的源文件(.c或.cpp)中定义函数实体,例如:

  1. // myheader.c
  2. #include "myheader.h"

  3. void myFunction() {
  4.     // 函数实现
  5. }

使用inline关键字(C++):
如果你确实需要在头文件中定义函数,可以使用inline关键字(适用于C++)。inline函数允许在多个编译单元中定义相同的函数,而不会导致链接错误。

  1. // myheader.h
  2. inline void myFunction() {
  3.     // 函数实现
  4. }
使用static关键字(C):
在C语言中,你可以使用static关键字将函数的作用域限制在当前编译单元内,这样即使多个源文件包含该头文件,也不会导致重复定义。

  1. // myheader.h
  2. static void myFunction() {
  3.     // 函数实现
  4. }



 楼主| heisexingqisi 发表于 2025-2-17 09:16 | 显示全部楼层
总结:
头文件:用于声明函数、变量、类等。
源文件:用于定义函数、变量、类等。
通过将声明和定义分开,可以避免重复定义的问题,并保持代码的模块化和可维护性。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

157

主题

2770

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部