首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

使用C++头文件(.h)与头文件加上实现(.h + .cpp),有哪些缺点?

使用C++头文件(.h)与头文件加上实现(.h + .cpp)的方式存在以下缺点:

  1. 编译速度慢:当头文件被多个源文件引用时,每个源文件都需要重新编译,导致编译时间增加。
  2. 代码冗余:头文件中通常包含类的声明和函数的定义,当多个源文件引用同一个头文件时,会导致代码冗余,增加了代码量。
  3. 难以维护:头文件中包含了类的声明和函数的定义,当需要修改类的定义或函数的实现时,需要同时修改头文件和源文件,容易出错。
  4. 编译依赖关系复杂:当头文件之间存在相互引用时,可能会导致编译依赖关系复杂,增加了编译的难度。
  5. 可见性问题:头文件中的内容对外是可见的,可能会暴露一些不应该对外暴露的实现细节,破坏了封装性。

为了解决这些问题,可以使用C++的模块化编程方式,将声明和实现分离,以减少编译时间和代码冗余。另外,使用命名空间可以避免全局命名冲突,提高代码的可维护性。对于大型项目,可以使用构建工具来管理编译依赖关系,如CMake、Makefile等。

腾讯云相关产品和产品介绍链接地址:

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C++ 头文件使用 .h 还是 .hpp

问题 我在写 C++ class 的定义部分时,代码都是放在后缀 *.h 文件中,最近在接触 Boost 库的时候发现里边使用的都是 *.hpp 后缀,那么两者在使用上有什么区别?...回答 *.hpp (或 *.hxx, *.hh …)只适用 C++,而 *.h C 和 C++ 都适用。 后缀命名不同的优点: 代码自动格式化。...一些插件可以根据后缀来自动区分哪个是 C 代码,哪个是 C++,来进行对应的格式化。 语言区分。从后缀就可以很容易区分,这个文件下是 C 还是 C++。 文件命名。...C++ 很容易引入 C 库,如果引入了一个 C 库内的头文件 feature.h,而 C++ 不得不对这个文件的代码进行面向对象设计,那么为了保持命名和语义上的统一,将 C++ 文件命名为 feature.hpp

65110
  • hpp头文件h头文件的区别 C++中的.hpp文件

    hpp,其实质就是将.cpp实现代码混入.h头文件当中,定义实现都包含在同一文件,则该类的调用者只需要include该hpp文件即可,无需再将cpp加入到project中进行编译。...而实现代码将直接编译到调用者的obj文件中,不再生成单独的obj,采用hpp将大幅度减少调用 project中的cpp文件数编译次数,也不用再发布烦人的libdll,因此非常适合用来编写公用的开源库...2、*.h类似,hpp是C++程序头文件 。 3、是VCL专用的头文件,已预编译。 4、是一般模板类的头文件。...5、一般来说,*.h里面只有声明,没有实现,而*.hpp里声明实现都有,后者可以减少.cpp的数量。 6、*.h里面可以using namespace std,而*.hpp里则无。...在.h和.cpp的场景中,当两个类或者多个类之间循环调用关系时,只要预先在头文件做被调用类的声明即可,如下: class B; class A{ public:

    4.3K20

    C++】泛型编程 ⑪ ( 类模板的运算符重载 - 函数实现 写在类外部的不同的 .h 头文件和 .cpp 代码中 )

    将 类模板 函数声明 函数实现 分开进行编码 , 三种 方式 : 类模板 的 函数声明 函数实现 都写在同一个类中 , 也就是没有分开进行编码 ; 类模板 的 函数实现 在 类外部进行 ,...函数声明 和 实现 写在相同的 .cpp 源码文件中 ; 类模板 的 函数实现 在 类外部进行 , 函数声明 和 实现 写在不同的 .h 和 .cpp 源码文件中 ; 在博客 【C++】泛型编程 ⑨ (...; 一、类模板的运算符重载 - 函数实现 写在类外部的不同的 .h 头文件和 .cpp 代码中 1、分离代码 后的 友元函数报错信息 - 错误示例 上一篇博客 【C++】泛型编程 ⑩ ( 类模板的运算符重载...; 将上述源码 分别写到 .h 头文件 , .cpp 代码文件 中 ; Student.h 头文件内容 Student.h 头文件内容 : #include "iostream" using namespace...、代码示例 - 函数实现 写在类外部的不同的 .h 头文件和 .cpp 代码中 1、完整代码示例 Student.h 头文件内容 Student.h 头文件内容 : #include "iostream

    22510

    C++】面向对象示例 - 数组类 ( 示例需求 | 创建封装类 | 数组类头文件 Array.h | 数组类实现 Array.cpp | 测试类 Test.cpp - 主函数入口 )

    和 Array.cpp 源码文件 ; 2、生成的类源码内容 Array.h 源码内容为 : #pragma once 的作用是防止被二次导入 , 导致 Array 类重复定义 ; #pragma once...class Array { }; Array.cpp 源码内容为 : 用于实现 Array 中的成员函数 , 成员函数之前使用 Array:: 域作用符 ; #include "Array.h" 三、...数组类实现 ---- 1、数组类头文件 Array.h 在 数组类 的头文件中 , 对 成员方法 和 成员变量 进行声明定义 ; 成员方法 只进行声明 , 不进行实现 ; 该 Array 类 定义了 构造... 析构 函数 4 个 : 无参构造函数 : Array(); 参构造函数 : Array(int len); 拷贝构造函数 : Array(const Array& array); 析构函数...Array.cpp 在本代码中 , 主要对 构造函数 , 析构函数 , 成员函数 进行实现 ; 注意 , 此处的拷贝构造函数 , 使用的是深拷贝机制 , 数组的内存重新进行了申请 , 然后将原数组的元素值

    37130

    学习PCL库你应该知道的C++特性

    基本介绍请查看文章:点云及PCL编程基础 .h和.hpp文件的区别 *.h类似,hpp是C++程序头文件,其实质是将cpp中的实现代码放在.hpp文件中,定义实现都包含在同一个文件中,在使用的时候只需要...该文件具有的特点: .hpp.h文件类似,hpp也是C++程序的头文件。 是一般模板类的头文件 一般来说。....h文件只有申明,没有函数的实现,.hpp里申明实现都有,后者可以减少cpp的数量 *.h里面可以using namespace std,而*.hpp里尽量不要出现。...类之间不可循环调用:在.h和.cpp的场景中,当两个类或者多个类之间循环调用关系时,只要预先在头文件做被调用类的声明即可。...对应的缺点就是如果某个头文件多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名碰撞引发的"找不到声明"的问题,重复包含更容易被发现并修正。

    1.2K20

    PCL库中的C++特性

    基本介绍请查看文章:点云及PCL编程基础 .h和.hpp文件的区别 *.h类似,hpp是C++程序头文件,其实质是将cpp中的实现代码放在.hpp文件中,定义实现都包含在同一个文件中,在使用的时候只需要...该文件具有的特点: .hpp.h文件类似,hpp也是C++程序的头文件。 是一般模板类的头文件 一般来说。....h文件只有申明,没有函数的实现,.hpp里申明实现都有,后者可以减少cpp的数量 *.h里面可以using namespace std,而*.hpp里尽量不要出现。...类之间不可循环调用:在.h和.cpp的场景中,当两个类或者多个类之间循环调用关系时,只要预先在头文件做被调用类的声明即可。...对应的缺点就是如果某个头文件多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名碰撞引发的"找不到声明"的问题,重复包含更容易被发现并修正。

    1.1K30

    CC++头文件的作用和用法

    ---- 头文件是C/C++程序不可缺少的组成部分,使用时,应该了解头文件的作用和相关规范。 1.头文件的作用 C/C++编译采用的是分离编译模式。...2.2使用系统提供的头文件 C语言提供的头文件都是以.h结尾的,如stdio.h等。C++语言最初的目的是成为一个“更好的C”,所以C++语言沿用了C语言头文件的命名习惯,将头文件后面加上.h标志。...于是,在一段时间里,很多头文件两个版本,一个以.h结尾,而另一则不是,如iostream.h(位于全局名字空间)和iostream(位于名字空间std)。...std; 这种现象有些混乱,于是C++标准委员会规定,旧C头文件(如stdio.h)和C++中新的C头文件(如cstdio)继续使用,但是旧的C++头文件(如iostream.h)已被废弃,一律采用C...此外,也可以使用#paragma once预处理指令来实现,但这种方法并非所有编译器都支持,考虑到代码的可移植性,建议使用条件编译预处理指令。

    4.3K11

    【Linux】编译器-gccg++使用

    将test.cc先改名为test.cpp: mv test.cc test.cpp 然后编译test.cpp,再指向a.out C++代码后缀除了.cc和.cpp之外,还有一个.cxx 来直接编译一下...是从test.c的头文件 #include来的。...怎么知道库里面有哪些文件? 会有一批对应的头文件,这个头文件相当于一个方法说明。 所以安装开发环境是:安装C标准库和C头文件 库分为动态库和静态库。...查看文件类型: file my.exe 使用的是动态库链接: 动态库和动态链接的优缺点: 不能丢失 节约资源 重新创建一个文件夹,把test.c移动到里面,然后执行。...静态库和静态链接的优缺点: 一旦形成,库无关 浪费资源 形成静态链接: gcc -o mytest-static test.c -static - 发现报错了: 这个是因为在默认情况下,一般静态库都是默认没有安装的

    17410

    C++】类的声明 类的实现 分开 ② ( 头文件导入多次报错 | 头文件的作用 | 类的声明 | 类的实现 | 代码示例 - 类的使用 )

    一、头文件导入多次报错 1、头文件没有 #pragma once 报错 在 .cpp 源码文件中 , 使用 #include "Student.h" 代码 , 包含头文件 , 使用 #include "...========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ========== 2、头文件加上 #pragma once 编译成功 在头文件中 , 加上了 #pragma...两种情况下是需要导入 .h 头文件 的 : 以 实现 声明的 变量 / 类 / 函数 为目的 , 自己开发函数库 给别人用 ; 以 使用 声明的 变量 / 类 / 函数 为目的 , 使用别人开发的函数库...成员属性 和 成员函数 ; 不实现 成员函数 ; 成员函数 在 对应的 Student.cpp实现 ; 代码示例 : // 确保 该头文件 只包含一次 #pragma once /* // C...getAge(); }; 四、类的实现 ---- 在 Student.cpp 源码中 , 导入 Student.h 头文件 , 这是 创建 Student 类时自动生成的 ; 在类中声明成员函数 void

    49440

    一个C#开发者重温C++的心路历程

    比如上面的代码,我们将其中的引用头文件使用命名空间的代码提取出来,写进pch.h头文件;然后,我们得到代码如下图: pch.h头文件: ? ConsoleTest.cpp文件: ?...,使用的引用方法是【#include 】;我发现,引用该头文件时,并没有加后缀.h;我把后缀.h加上后【#include 】,发现编译依然可以通过。...CinCout CinCout是控制台的输入和输出函数,我在测试时发现,使用CinCout需要引用iostream头文件【#include 】,同时也要使用命名空间std。...不过在C++中,因为,引用困难的原因(上面已经描述了,只能引用其他.cpp文件对应的头文件,并且,.cpp实现的变量,还得在头文件里外部声明一下),所以类的定义写法也发生了改变。...C++中创建类,需要在头文件中声明函数,然后在.cpp文件中,做函数实现。 但是这样做,明显是跨文件声明类了,但C++中又没有类似partial关键字让俩个文件合并编译,那么怎么办呢?

    83430

    C++:04---内联函数

    建议声明和定义都加上inline inline int add(int a,int b) { return a+b; } 3.内联的优、缺点: 优点:避免了函数调用的开销,加快了代码的运行速度,避免频繁调用函数对栈内存带来的消耗...缺点:浪费代码空间 4.使用内联的情况 不宜使用内联的情况:递归函数、或函数中含有循环结构(浪费时间)、或函数代码过长(消耗内存) 可使用内联的情况:内联一般在类中使用(函数内进行简单的赋值、或直接返回数据...所以说,C++ inline函数是一种“用于实现的关键字”,而不是一种“用于声明的关键字”。...然而, 实现代码理论上应该放在 .cc 文件中, 我们不希望 .h 文件中有太多实现代码, 除非在可读性和性能上有明显优势....这样把实现和类定义分离开来, 当需要时包含对应的 -inl.h 即可。

    1.3K40

    详细剖析 extern C

    你说的没错,如果你的头文件从来没有被任何C++程序引用过的话。 这与C++什么关系呢? 看看__cplusplus(注意前面是两个下划线) 的名字你就应该知道它与C++很大关系。...我们先来看一个例子,现有a.h,b.h,c.h以及foo.cpp,其中foo.cpp包含c.h,c.h包含b.h,b.h包含a.h,如下: 现使用C++编译器的预处理选项来编译foo.cpp,得到下面的结果...比如:两个头文件a.h,b.h,其中b.h包含a.h,如下: 按照a.h作者的本意,函数foo是一个C++自由函数,其链接规范为"C++"。...Q: 如果我的C+ +程序想包含一个C头文件a . h,它的内容包含了C的函数/变量声明,但它们却没有使用e x t e r n "C"链接规范,该怎么办? A: 在a.h里面加上它。...某些人可能会建议你,如果a.h没有extern "C",而b.cpp包含了a.h,可以在b.cpp加上 : extern "C" {   #include "a.h" } 这是一个邪恶的方案,原因在之前我们已经阐述

    1.3K30

    C++编译链接(0)-.h.cpp中的定义声明

    C++中有的东西需要放在可以在.h文件中定义,有的东西则必须放在.cpp文件中定义,有的东西在不同的cpp文件中的名字可以一样,而有的则不能一样 那么究竟哪些东西可在头文件中定义,声明,哪些东西又必须在...static函数 在不同的cpp中可以定义函数原型一样的函数 类 不同的cpp中类的名字可以一样 类成员函数 在.h中定义,所有成员必须在类中声明,在cpp实现 非静态的常量整形数据成员不能就地初始化...(*C++11中,标准允许使用等号=或者花括号{}进行就地的非静态成员变量初始化) 在类内部定义的成员函数将自动作为inline处理 在.h外部定义的函数需要加上inline说明 否则在被include...- 不可以 (*C++11中,标准允许使用等号=或者花括号{}进行就地的非静态成员变量初始化) 类成员函数 ------------------ ---------------- 在.h外部定义的函数需要加上...需要到头文件以外去定义它) 类的静态的常量整形数据成员 ------------------ 可以 特殊说明 模板 模板函数模板类的声明实现必须放在一个文件中 至于为什么会这样,C++的编译和链接

    3.6K70

    C和C++混合编译,extern和extern C

    被extern “C”修饰的函数或者变量是按照C语言方式编译和链接的,所以可以用一句话来概括extern “C”的真实目的:实现C++C的混合编程。...x, int y) { return x + y; } /* c++实现文件,调用add:cppFile.cpp */ extern "C" { #include "cExample.h..."; } int main() {  add(2, 3);  return 0;  } `    如果C++调用一个C语言编写的.DLL时,在包含.DLL的头文件或声明接口函数时,应该也要加上...(2) C中引用C++语言中的函数或者变量时,C++头文件需要加上extern “C”,但是C语言中不能直接引用声明了extern “C”的该头文件,应该仅在C中将C++中定义的extern “C”函数声明为...笔者编写的C引用C++函数的例子工程,源文件代码如下:  /* c++头文件cppExample.h */ #ifndef CPP_EXAMPLE_H #define CPP_EXAMPLE_H

    3.5K11

    google C++编程风格指南之头文件的包含顺序

    google C++编程风格对头文件的包含顺序作出如下指示: (1)为了加强可读性和避免隐含依赖,应使用下面的顺序:C标准库、C++标准库、其它库的头文件、你自己工程的头文件。...不过这里最先包含的是首选的头文件,即例如a.cpp文件中应该优先包含a.h。首选的头文件是为了减少隐藏依赖,同时确保头文件实现文件是匹配的。...具体的例子是:假如你一个cc文件(linux平台的cpp文件后缀为cc)是google-awesome-project/src/foo/internal/fooserver.cc,那么它所包含的头文件的顺序如下...(2)在包含头文件时应该加上头文件所在工程的文件夹名,即假如你有这样一个工程base,里面有一个logging.h,那么外部包含这个头文件应该这样写:#include "base/logging.h",...因此我觉得更准确的说法应该是:OS SDK .h , C标准库、C++标准库、其它库的头文件、你自己工程的头文件

    2.6K10

    头文件里面的ifndef defineendif的作用

    大家好,又见面了,我是全栈君 c,c++里面,头文件里面的ifndef /define/endif的作用 今天和宿舍同学讨论一个小程序,发现有点地方不大懂······ 是关于头文件里面的一些地方...刚才上网查了查,借鉴了点高手的,自己总结了一点,就写在这里了,什么错误之处,请大侠们指出 1.比如你两个C文件,这两个C文件都include了同一个头文件。...例如: 假设你的工程里面有4个文件,分别是a.cpp,b.h,c.h,d.h。...加上ifndef/define/endif,就可以防止这种重定义错误。 所以还是把头文件的内容都放在#ifndef和#endif中吧。 不管你的头文件会不会被多个文件引用,你都要加上这个。...原因: (1).当你第一个使用这个头的.cpp文件生成.obj的时候,int i 在里面定义了当另外一个使用这个的.cpp再次[单独]生成.obj的时候,int i 又被定义然后两个

    59320

    C++服务编译耗时优化原理及实践

    一、背景 美团搜索NLP部为公司提供基础的搜索平台服务,出于性能的考虑,底层的基础服务通过C++语言实现,其中我们负责的深度查询理解服务(Deep Query Understanding,下文简称DQU...分布式编译 使用分布式编译技术,比如利用Distcc和Dmucs构建大规模、分布式C++编译环境,Linux平台利用网络集群进行分布式编译,需要考虑网络时延网络稳定性。...动态库、静态库、子仓库等,这个工具提供的优化功能不能直接使用,其它团队如果代码结构比较简单的话,可以考虑使用这个工具分析优化,会生成如下结果文件,指导哪些头文件需要删除。...一个显著缺点是其实现采用了hpp的形式,即声明和实现均放在头文件中,这会造成预编译展开后十分巨大。...通过比较相邻两个版本的CF,就能较准确的知道新版带来的编译耗时主要由哪些改动引入,并可以进一步分析耗时上涨是否合理,是否优化空间。

    1.9K20

    lib文件和dll文件的区别_dll2lib

    使用静态编译的lib文件,在运行程序时不需要再挂动态库,缺点是导致应用程序比较大,而且失去了动态库的灵活性,发布新版本时要发布新的应用程序才行。...文件数量的区别 (静态连接)使用lib需注意两个文件: .h头文件,包含lib中说明输出的类或符号原型或数据结构。应用程序调用lib时,需要将该文件包含入应用程序的源文件中。 .LIB文件,略。...(动态连接)使用dll需注意三个文件: .h头文件,包含dll中说明输出的类或符号原型或数据结构的.h文件。应用程序调用dll时,需要将该文件包含入应用程序的源文件中。...中的内容(将原来代码中,除头文件引入部分的代码外全部删除),并在后面新增你要实现的函数声明(见代码第26行)。...4.2 vs的常用操作 添加头文件: 配置属性–>C/C++–>常规–>附加包含目录 加上头文件存放的目录。

    2.7K10

    JNI中native方法的几种注册方式

    类 2.编译生成class文件 3.利用javah生成(.h)的头文件 命令:javah 类名, 注:不需要class后缀 4.将(.h头文件复制到vs下,创建(.cpp)或者(.c)文件实现(....h头文件声明的方法 5.实现完成后,编译成dll库 6.将dll复制到java项目的根目录,调用System.loadLibrary("dll库名"); //注:不要dll后缀 7.在代码里面调用...方法来注册 java 方法 JNI 函数的一一对应关系 实现流程 利用结构体 JNINativeMethod 数组记录 java 方法 JNI 函数的对应关系; 实现 JNI_OnLoad 方法,...,方法的签名 fnPtr 是函数指针,用来指向 jni 函数 区别: 静态注册 优点: 理解和使用方式简单, 属于傻瓜式操作, 使用相关工具按流程操作就行, 出错率低 缺点: 当需要更改类名,包名或者方法时..., 需要按照之前方法重新生成头文件, 灵活性不高 动态注册 优点: 灵活性高, 更改类名,包名或方法时, 只需对更改模块进行少量修改, 效率高 缺点: 对新手来说稍微有点难理解, 同时会由于搞错签名

    1.9K30
    领券