* .h或者* .hpp用于类定义
我一直在类定义中使用* .h
文件,但是在阅读了一些Boost库代码之后,我意识到它们都使用了* .hpp`。我一直对该文件扩展名有所厌恶,主要是因为我不习惯使用该文件扩展名。
与* .h
相比,使用* .hpp有什么优缺点?
解决方案
使用哪个扩展名都无关紧要。两者都可以。
我对C使用* .h
,对C ++使用* .hpp
。
我们可以随心所欲地调用包含。
只需在#include中指定该全名即可。
我建议如果我们使用C使用.h
,以及何时使用C ++使用.hpp`。
最后只是一个约定。
Codegear C ++ Builder将.hpp用于从Delphi源文件自动生成的头文件,并将.h文件用于"自己的"头文件。
因此,当我编写C ++头文件时,我总是使用.h。
在90年代初我的一项工作中,我们分别将.cc和.hh用作源文件和头文件。我仍然比所有其他方法都更喜欢它,可能是因为它最容易输入。
我最近开始将* .hpp
用于c ++头文件。
原因是我将emacs用作主编辑器,并且在加载* .h
文件时它自动进入c模式,而在加载* .hpp
文件时它自动进入c ++模式。
除此之外,我认为没有充分的理由选择* .hpp而不是* .hpp,反之亦然。
源文件的扩展名可能对构建系统有意义,例如,makefile中可能有一个.cpp或者.c文件的规则,或者编译器(例如Microsoft的cl.exe)可能根据扩展名将文件编译为C或者C ++。
因为必须将整个文件名提供给#include指令,所以头文件扩展名是无关紧要的。如果愿意,可以在另一个源文件中包含.c
文件,因为它只是文本包含。编译器可能有一个选项来转储经过预处理的输出,这将使这一点变得很清楚(Microsoft:/ P
预处理到文件,/ E
预处理到stdout
,/ EP
省略#line
指令,/ C
保留评论)
我们可能会选择对仅与C ++环境相关的文件使用.hpp,即它们使用的功能不会在C中编译。
以下是C与C ++标头命名不同的几个原因:
- 自动代码格式化,我们可能对格式化C和C ++代码有不同的指导。如果标题以扩展名分隔,则可以将编辑器设置为自动应用适当的格式
- 命名,我去过的项目中有一些用C编写的库,然后用C ++实现了包装器。由于标头通常具有相似的名称,即Feature.h与Feature.hpp,因此很容易区分。
- 包括在内,也许项目有可用C ++编写的更合适的版本,但是我们使用的是C版本(请参见上文)。如果标头是以其实现的语言命名的,则可以轻松发现所有C标头并检查C ++版本。
记住,C不是C ++,除非我们知道自己在做什么,否则混搭会非常危险。适当地命名源可区分语言。
对于C ++,我更喜欢使用.hpp来使编辑者和其他程序员都清楚它是C ++头文件而不是C头文件。
我使用.h,因为这是Microsoft使用的,以及它们的代码生成器创建的内容。无需违反常规。
我一直认为.hpp
标头是.h
和.cpp
文件的写法……标头也包含实现细节。
通常,当我看到(并使用).hpp作为扩展名时,没有相应的.cpp文件。正如其他人所说,这不是一个硬性规定,这只是我倾向于使用.hpp
文件的方式。
C ++(" C Plus Plus")与.cpp一样有意义
具有扩展名为.hpp的头文件不会具有相同的逻辑流程。
我使用.hpp是因为我希望用户区分哪些标头是C ++标头,哪些标头是C标头。
当项目同时使用C和C ++模块时,这可能很重要:就像在我之前解释过的其他人一样,我们应该非常小心地进行操作,它的开始是通过扩展提供的"合同"
(或者.hxx或者.hh或者其他)
此标头仅适用于C ++。
如果我们在C模块中,甚至不要尝试包含它。我们不会喜欢它,因为没有做出任何努力使其成为C友好的(将丢失太多,例如函数重载,名称空间等)。
此标头可以直接或者间接地包含在C源代码和C ++源代码中。
它可以直接包含,受__cplusplus
宏保护:
- 这意味着,从C ++的角度来看,与C兼容的代码将被定义为"外部" C"。
- 从C的角度来看,所有C代码都将清晰可见,但是C ++代码将被隐藏(因为它将无法在C编译器中编译)。
例如:
#ifndef MY_HEADER_H #define MY_HEADER_H #ifdef __cplusplus extern "C" { #endif void myCFunction() ; #ifdef __cplusplus } // extern "C" #endif #endif // MY_HEADER_H
或者可以通过相应的.hpp标头间接包含它,并用extern" C"
声明将其括起来。
例如:
#ifndef MY_HEADER_HPP #define MY_HEADER_HPP extern "C" { #include "my_header.h" } #endif // MY_HEADER_HPP
和:
#ifndef MY_HEADER_H #define MY_HEADER_H void myCFunction() ; #endif // MY_HEADER_H