当前位置: 首页 > news >正文

c++的头文件到底应该怎么写?

总结一下头文件的编写规则和注意事项:

  1. 头文件的作用是供其他的 .cpp 文件包含,它们本身不直接参与编译,但其内容会在多个 .cpp 文件中被编译。

  2. 头文件中应该只放变量和函数的声明,而不能放它们的定义。因为头文件的内容会被多个 .cpp 文件包含,如果放置定义,会导致同一个符号(变量或函数)在多个文件中被定义,违反了"定义只能有一次"的规则。

  3. 头文件中可以放置以下三种例外情况的定义:

    • const 对象的定义:因为全局的 const 对象默认没有 extern 声明,所以它只在当前文件中有效,不会导致多重定义。
    • 内联函数(inline)的定义:内联函数需要在编译时看到完整定义,且可以在程序中定义多次,只要在每个 .cpp 文件中只出现一次且定义相同。
    • 类(class)的定义:创建类对象时,编译器需要知道类的完整定义才能确定对象的布局。可以把类的定义放在头文件中,函数成员的实现代码放在 .cpp 文件中,或者直接将函数成员的实现写进类定义中。
  4. 为了防止头文件被同一个 .cpp 文件多次包含导致的问题,可以使用头文件保护措施,即通过 #define 定义一个名字,并使用条件编译指令 #ifndef…#endif,让编译器根据这个名字是否被定义来决定是否继续编译头文件中的内容。

  5. 在编写头文件时,要特别注意使用头文件保护措施,以避免多重包含导致的编译错误。

总之,头文件的编写需要遵循一定的规则,合理划分声明和定义,并且要注意使用头文件保护措施。遵循这些规则和注意事项,可以有效避免头文件在多个 .cpp 文件中包含时导致的编译和链接错误。


当你在头文件中写下像 int a;void f() {} 这样的语句时,实际上是在定义变量或函数,而不仅仅是声明。如果这个头文件被多个源文件包含,那么每个源文件都会有一个变量 a 或函数 f 的定义。在编译阶段,每个源文件都会独立编译,生成对应的目标文件(.o或.obj文件)。

问题出现在链接阶段。当链接器尝试将所有目标文件合并成一个可执行文件或库文件时,它会发现有多个 a 变量或 f 函数的定义。这违反了C++的一个规则:一个变量或函数只能有一个定义(One Definition Rule,ODR)。因此,链接器会报错,指出存在重复的符号定义。

为了避免这个问题,我们通常在头文件中只包含变量或函数的声明,而将它们的定义放在对应的源文件中。声明的作用是告诉编译器这个符号的存在,以及它的类型和签名等信息。而定义则提供了符号的实际内容或实现。

例如,在头文件中,我们可以写:

// MyHeader.h
extern int a;
void f();

然后在对应的源文件中提供定义:

// MySource.cpp
#include "MyHeader.h"int a = 42;
void f() {// 函数的实现
}

通过这种方式,我们可以在多个源文件中包含同一个头文件,而不会导致重复定义的错误。编译器会在编译每个源文件时使用头文件中的声明,而在链接阶段,链接器会找到变量 a 和函数 f 的唯一定义,并正确地生成最终的可执行文件或库文件。

这就是为什么我们通常遵循这样的规则:在头文件中只写声明,而在源文件中写定义。这有助于避免由于重复定义而导致的编译和链接错误。

参考链接:https://www.cnblogs.com/lidabo/archive/2012/04/17/2454568.html


http://www.mrgr.cn/news/57163.html

相关文章:

  • 数学之美——程序员的专属浪漫
  • C++|bitset模板类
  • [电子科大]王丽杰 离散数学 第二讲 特殊集合和集合间关系 笔记
  • SSRF-利用dict协议-攻击redis
  • 技术经济学·技术经济分析指标体系与基本原则
  • 每日OJ题_牛客_字符串分类_哈希+排序_C++_Java
  • 【编程语言】Kotlin快速入门 - 高阶函数与运算符重载
  • 均匀随机掉落算法
  • 梦开始的地方 -- 两数求和
  • c++查看运行时类型
  • Thread类
  • react优化
  • Napkins:开源 AI 开发工具,实现截图或线框图到网页应用的快速转换
  • konva不透明度,查找,显示,隐藏
  • vTESTstudio系列14--vTESTstudio中自定义函数介绍1
  • RHCE时间服务器
  • Vscode + EIDE +CortexDebug 调试Stm32(记录)
  • Kamailio 网络拓扑案例分享
  • C++ set和map的模拟实现
  • Llama Tutor:开源 AI 个性化学习平台,根据主题自动制定学习计划
  • RTDETR 引入 MogaBlock | 多阶门控聚合网络 | ICLR 2024
  • ThinkPad中键打开网页关闭网页失灵
  • 【Linux】线程互斥与同步,生产消费模型(超详解)
  • Redis-05 Redis发布订阅
  • 得物App3D博物馆亮相“两博会”,正品保障助力消费体验升级
  • 10.23Python_matplotlib_乱码问题