C++之*.h和*.cpp文件详解

*.h文件做的是类的声明,包括类成员的定义和函数的声明,而*.cpp文件做的类成员函数的具体实现(定义)。一个*.h文件和*.cpp文件一般是配对的。在*.cpp文件的第一行一般也是#include"*.h"文件,其实也相当于把*.h文件里的东西复制到*.cpp文件的开头。所以,你全部写在*.cpp文件其实也是一样的。h的作用体现在当多个cpp文件需要同一份变量、类型、函数或宏定义之类的话,我们不需要在这些cpp文件中一一声明,只需要在.h文件中声明,然后在这些cpp文件中把这个.h文件包含进去就OK了,对于简短的小程序,.h往往显得多余,因为.h文件重复使用的次数,还不如放在cpp文件中方便。但对于较大的程序来说,使用.h是非常方便的!


除了编程规范外,还涉及到类一个重要性质,就是封装性。比如现在我们公司和另一家软件公司合作,这样就必然要互相提供一些软件的信息(比如一些类,它到底是要做什么的),可是在提供这些信息的同时我们又不像让对方知道我们这些类的具体实现,毕竟这些是我们公司的算法核心和心血啊。所以这个时候就可以把类的接口(这个类是要做什么的)放在*.h文件中,而具体类的实现放在 *.cpp文件。这时候我们只要给对方公司*.h文件就行了。这样既提供了必要的信息,又保护了我们的核心代码。

 

最表面的机制是:

头文件是程序的界面(是代码界面),提供给程序员以类、模版、函数等一系列的声明,让程序员知道应该怎么调用里面的“东西”。

从动态链接库的角度看:

头文件提供界面,使得程序员在需要加载一个库函数的时候(这里也仅仅是举简单的例子)查看头文件就知道怎么加载这个动态库内部的函数。

 

从软件的扩展来说:

将头文件作为界面,再去定义它的实现,这样只要保证界面不变(头文件不变),就可以只修改实现文件,而不必修改其他的实现代码。比如你有一个sort()函数来排序,在一个大程序中,你后来发现这个sort()有更好的算法,于是你只需要去修改函数的实现(修改.cpp文件的sort()函数的代码),其他使用这个函数的地方可以完全保持不变,这是分割技术的第一个好处。

 

从模块性来讲:

界面后面隐藏实现代码,代码具有更好的物理模块性,减小程序的复杂度。 

 

从编译的角度看:

所有源文件都是被编译器分别划分单元来分别编译,在编译的过程中,头文件被嵌入到实现文件里面一起作为一个编译单元被编译(实现文件filename.cpp里的

#include "filename.h"

那一行被替换成filename.h里面的所有内容(实际上会把预处理指令去掉,这才是预处理最本质的作用))。

举一个简单的例子,你定义了sort( )函数,在test.h头文件里声明,在test.cpp里定义,这个时候在test.cpp里面#include "test.h",并定义sort( )函数。

你需要在头文件内部写预处理代码

#ifndef _TEST_H_

#define _TEST_H_

 

#endif

预处理指令防止头文件被多重包含,如果你的代码出现了诡异的错误,请注意这个问题,可能是你没有写头文件保护,在符号链接阶段链接器发现有多个相同的名字,它不知道应该跟哪一个符号链接在一起,所以报错。在头文件中使用#ifdef和#ifndef是非常重要的,可以防止双重定义的错误。如你在头文件aaa.h中定义了一个类aaa如下:   

  class   aaa   
  {

   
  };   
  如果两次#include   "aaa.h"(不见得是直接,也有可能两个不同的头文件中都包含了这个头文件)就会出错,因为相同的类不能定义两次。把aaa.h稍做修改:   
  #ifndef   _aaa_   
  #define   _aaa_   
  class   aaa   
  {  

 
  };   
  #endif   

就可以避免这样的问题。因为当你已经包含过这个文件,_aaa_就会有了定义,那么#ifndef的条件为假,就不会再执行后面的类定义了。

 

从节约时间的角度看:

在一些大型项目里面,编译一个项目不是整个一起同时编译的,一般情况是分别交给几个负责人去编译,测试,最后链接起来。如果中间发现有一个实现文件有BUG,只需要修改这个.cpp文件,其他的文件就可以原封不动。

再重新编译的时候,只需要单独便宜修改过的这一块,其他的部分不动。然后再链接成可执行程序。

这种机制在一个可能完整编译需要花费超级计算机几天时间的项目上是非常有用的,想一下,没有这种机制,要是一个程序随便修改一个地方。这个程序就要花几天时间来编译,这事情,怎么了得?

 

使用连接器的两个原因:

1.编译成目标文件的时候代码的内部符号被编译器修改过。

2.目标文件被组织成一个整的大型文件,所有符号被定位,保证每一个函数调用都找得到他本身的定义位置


  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
psins.cpp是一段C++代码,它主要实现了一种称为“粒子群算法”的优化算法。该算法最初由Eberhart和Kennedy于1995年提出,旨在解决优化问题,尤其是寻找复杂非线性问题的全局最优解。本次详解将从算法原理、程序结构和实现细节三个方面来阐述psins.cpp。 首先,psins.cpp实现的算法原理是粒子群算法。这是一种模拟群体行为的启发式优化算法,它通过模拟鸟群或鱼群等自然群体的行为方式,来寻找全局最优解。在算法执行过程,粒子数量和位置表示待解优化问题的解空间,每个粒子都根据自己在解空间的位置和速度,以及其与周围粒子的交互信息,来更新自己的位置和速度。这样,粒子群可以在解空间搜索最优解,并逐渐收敛于全局最优解。 其次,psins.cpp的程序结构主要包括初始化、更新粒子位置和速度、计算适应度函数和更新全局最优解四个阶段。在初始化阶段,算法需要设置粒子数量、搜索范围、速度范围、惯性权重等参数,以及随机生成初始粒子位置和速度。在更新粒子位置和速度阶段,粒子会根据自己的位置、速度、惯性权重、个体经验和全局经验等因素,更新自己的位置和速度。在计算适应度函数阶段,算法将根据当前粒子位置计算适应度函数值,用来评价当前解是否优秀。在更新全局最优解阶段,算法将比较所有粒子的适应度函数值,选出全局最优解并更新。 最后,psins.cpp还包括一些实现细节,如使用矩阵和随机数生成器等库函数、使用静态变量和宏定义等优化代码结构、使用C++面向对象风格等。这些细节可以提高代码的可读性和可维护性,同时也确保程序执行效率和数值精度等方面的性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值