C++中.cpp和.hpp的区别

2023-11-13

时间 2020-06-02

标签 c++ cpp hpp 区别

栏目 C&C++繁體版

原文 https://my.oschina.net/u/4398200/blog/3336507

原文地址:https://blog.csdn.net/qzx9059/article/details/89210571ios

c++中 cpp和hpp

咱们能够将全部东西都放在一个.cpp文件内,编译器会将这个.cpp编译成.obj,即编译单元。一个程序能够由一个编译单元组成,也能够由多个编译单元组成。一个.cpp对应一个.obj,而后将全部的.obj连接起来(经过一个叫连接器的程序),组成一个.exe,即程序。若是一个.cpp要用到另外一个.cpp定义的函数怎么办,只需在这个.cpp中写上它的函数声明。 连接器将全部的obj连接起来,可是若是碰巧有相同的函数或外部变量怎么办?C++能够经过一种叫作连接属性的关键字来限定,某个函数是属于整个程序公用的,仍是只在一个编译单元obj里面使用,这些关键字就是extern(外部连接)和static(内部连接)。让咱们说说.h。其实没有.h,程序也能很好的工做,可是当你发现一个外部连接的函数或外部变量,须要许多分声明,由于只要使用到该函数的单元,就必须写一份声明在那个.cpp里面,若是要修改会很麻烦!!!.h就是为了解决这个问题而诞生的,它包含了这些公共的东西,而后全部须要使用该函数的.cpp,只须要用#include包含进去即可,之后须要修改,只是修改一分内容。#include并非什么申请指令,只是将指定文件的内容,原封不动的拷贝进来。

不是很严格的讲,.h文件作的是类的声明,包括类成员的定义和函数的声明,而.cpp文件作的类成员函数的具体实现(定义)。一个*.h文件和*.cpp文件通常是配对的。在*.cpp文件的第一行通常也是#include".h"文件,其实也至关于把.h文件里的东西复制到*.cpp文件的开头。因此,你所有写在*.cpp文件其实也是同样的。

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

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

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

3.从软件的扩展来讲:将头文件做为界面,再去定义它的实现,这样只要保证界面不变(头文件不变),就能够只修改实现文件,而没必要修改其余的实现代码。好比你有一个sort()函数来排序,在一个大程序中,你后来发现这个sort()有更好的算法,因而你只须要去修改函数的实现(修改.cpp文件的sort()函数的代码),其余使用这个函数的地方能够彻底保持不变,这是分割技术的第一个好处

4.从编译的角度看:

全部源文件都是被编译器分别划分单元来分别编译,在编译的过程当中,头文件被嵌入到实现文件里面一块儿做为一个编译单元被编译(实现文件filename.cpp里的#include "filename.h"这一行被替换成filename.h里面的全部内容(实际上会把预处理指令去掉,这才是预处理最本质的做用))。

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

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

头文件的全部内容,都必须包含在

#ifndef {Filename}

#define {Filename}

12

//{Content of head file}   你的代码写在这里

#endif

这样才能保证头文件被多个其余文件引用(include)时,内部的数据不会被屡次定义而形成错误。

c++中头文件(.h)和源文件(.cpp)都应该写些什么?

头文件(.h):

写类的声明(包括类里面的成员和方法的声明)、函数原型、#define常数等,但通常来讲不写出具体实现。

头文件还能够定义:在编译的时候就已知道其值的cosnt对象和inline 函数。在头文件中定义上述实体,是由于编译器须要它们的定义来产生代码。

源文件(.cpp):

源文件主要写实现头文件中已经声明的那些函数的具体代码。须要注意的是,开头必须#include一下实现的头文件,以及要用到的头文件。那么当你须要用到本身写的头文件中的类时,只须要#include进来就好了。

下面举个最简单的例子来描述一下,咱就求个圆面积。

第1步,创建一个空工程(以在VS2003环境下为例)。

第2步,在头文件的文件夹里新建一个名为Circle.h的头文件,它的内容以下:

#ifndef CIRCLE_H

#define CIRCLE_H

class Circle

{

private:

double r;//半径

public:

Circle();//构造函数

Circle(double R);//构造函数

double Area();//求面积函数

};

#endif

12345678910111213141516

注意到开头结尾的预编译语句。在头文件里,并不写出函数的具体实现。

第3步,要给出Circle类的具体实现,所以,在源文件夹里新建一个Circle.cpp的文件,它的内容以下:

#include "Circle.h"

Circle::Circle()

{

this->r=5.0;

}

Circle::Circle(double R)

{

this->r=R;

}

double Circle:: Area()

{

return 3.14*r*r;

}

123456789101112131415161718

须要注意的是:开头处包含了Circle.h,事实上,只要此cpp文件用到的文件,都要包含进来!这个文件的名字其实不必定要叫Circle.cpp,但很是建议cpp文件与头文件相对应。

最后,咱们建一个main.cpp来测试咱们写的Circle类,它的内容以下:

#include <iostream>

#include "Circle.h"

using namespace std;

int main()

{

Circle c(3);

cout<<"Area="<<c.Area()<<endl;

return 1;

}

注意到开头时有#include "Circle.h"的声明,证实咱们使用到了咱们刚才写的Circle类。

1234567891011

至此,咱们工程的结构为:

注意这里声明与定义的区别:它们最本质的区别是定义只能够出现一次,声明能够出现屡次。声明不分配空间,而定义是要分配空间的。

———————————————— 版权声明:本文为CSDN博主「轻远清清」的原创文章,遵循 CC 4.0 BY-SA

版权协议,转载请附上原文出处连接及本声明。

原文连接:https://blog.csdn.net/qzx9059/article/details/89210571

相关文章

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++中.cpp和.hpp的区别 的相关文章

随机推荐

  • centos下安装apache

    下载所需要的包 wget http mirrors tuna tsinghua edu cn apache httpd httpd 2 4 54 tar gz wget http mirrors tuna tsinghua edu cn a
  • GnuTLS recv error (-110): The TLS connection was non-properly terminated问题的解决方案

    我在使用git clone branch 3 4 depth 1 https github com opencv opencv git命令的时候 遇到如下问题 fatal unable to access https github com
  • Radware负载均衡项目配置实战解析之一初识RADWARE(VIP与FARM配置)

    在近期的项目中 接触负载均衡设备RADWARE比较多 可能有很多朋友对这个设备还不是很了解 所以我把具体项目实战中的Radware配置应用与大家做一个分享交流 RADWARE是一家智能应用网络解决方案的全球领先供应商 主要生产应用交付和网络
  • Ubuntu下无法打开终端

    在安装某个版本的python并进行一系列自己也看不懂的配置之后 突然发现终端无法打开了 具体来说就是从桌面点击没有用 ctrl alt T也打不开 只能从选择文件夹 右击选择终端打开时可以 然后开始救赎之路 打开vscode的终端 或pyc
  • Python开发难学吗?简单易用适合初学者入门

    Python开发难学吗 适合初学者吗 Python入门阶段零基础学员打好基础是非常重要的 在非常高的抽象计算中 高级的Python程序设计非常难学 高级程序语言不等于简单 但对于初学者和完成普通任务Python语言是非常简单易用的 Pyth
  • 四、【服务器】服务器入门——常见单位

    U 高度单位 U 是UNIT的缩写 1U 4 445cm 是一种表示机架服务器外部尺寸的单位 指的是高度或者说厚度 规定这个尺寸是为了使得服务器保持适当的尺寸 在机柜安装的时候需要注意到留好安装高度 机架服务器通常宽度在19英寸 高度为1U
  • 小波分析

    本文首先介绍了从傅里叶变换到小波变换的发展史 然后着重强调了小波变换的两种作用 时频分析和多分辨率分析 最后讲了一下吉布斯效应等相关知识 FT 傅里叶变换 通过将信号分解成正余弦函数 把三角函数当做函数空间的基 将时域信号转化为频域信号 缺
  • Ubuntu16.04升级docker ce错误:Depends: libseccomp2 (>= 2.3.0) but 2.2.3-3ubuntu3 is to be installed

    环境 系统 Ubuntu16 04 docker old version Docker version 1 10 3 build 20f81dd 按照官方给出的步骤安装 https docs docker com install linux
  • DGL-kernel的变更(3)

    导读 DGL kernel中针对Graph的计算几个版本有了不小的变动 v0 3 0 4使用的是minigun v0 3和v0 4源码中主要相关部分则是在对应分支dgl src kernel目录下 v0 5中对kernel代码进行了重写 并
  • IOS学习笔记(十二)之IOS开发之表视图(UITableView)的相关类,属性与表视图实现学习(二)

    iOS学习笔记 十二 之IOS开发之表视图 UITableView 的讲解与使用 二 博客地址 http blog csdn net developer jiangqq 转载请注明地址 Author hmjiangqq Email jian
  • 记录一个问题maven jar 引入

    分模块创建项目jar包无法引入错误 明明在 确保错 无奈最后换个本地仓库地址 重新下载jar 结果不报错了 估计是jar包太多了 混乱导入造成的
  • MySQL中tinyint(1)与tinyint(2)的区别

    一 tinyint类型的介绍 1个tinyint类型的字段占用一个字节 一个int类型的字段占用四个字节 CREATE TABLE user id int 11 NOT NULL COMMENT ID age tinyint 1 NOT N
  • nginx配置SSL协议,80端口443端口。和非80/443端口

    1 80 443 server listen 80 server name www 域名 com rewrite https server name 1 permanent server listen 443 server name www
  • 前端项目查找网站有哪些?面试必看

    教你们一招 项目在这些地方找 面试官眼前一亮 还有一些面试技巧 收藏 工作年限 3 年工作经验 5个项目以上 2 年工作经验项目 4 个项目 技术栈 Vue vuex vue router webpack ES6 node vue reso
  • 兔子问题---细说斐波那契数列

    对于兔子问题的鼎鼎大名 相信很少有人没听过吧 为了完整性还是再说一下题目吧 题目描述 已知一对兔子每一个月可以生一对小兔子 而一对兔子出生后 第三个月开始生小兔子假如一年内没有发生死亡 则一对兔子开始 第N个月后会有多少对 这道题所描述的就
  • 解决IDEA2019.1.3无法创建包的子类包问题

    有时候我们需要创建包的子类包 空包 的时候我们发现 不知道如何在初始的包中创建子类包 随后在别的博客上看了好多解决方法 好多都是没有选中父类包 或者没有将下面这个选项勾掉 但是这个勾掉的话就把父类中最后一个包也变成了子类包 并没有达到我们所
  • “先裁掉女员工!”

    身为女性在职场 不得不面对一些尴尬的时刻 我朋友公司刚招了一个商务的妹纸 没几周就说自己怀孕了 紧接着 开启了三天打鱼两天晒网的请假模式 今年就业环境不太理想 朋友公司招人有严格的名额限制 考虑再三 上司和HR昨天找她面谈 上司说 市场岗压
  • leveldb 源码--总体架构分析

    一 本文目的 对leveldb的总体设计框架分析 关于leveldb基本原理 此文不做阐述 读者可以自行检索文章阅读即可 对leveldb中底层数据存储数据格式 内存数据模型 compact 版本管理 快照等机制实现介绍以及整个leveld
  • 弯道超车,阿里高工新产Java面试速成指南,面试骚操作都在里面了

    金三银四过去一半 市场火热 但是大家就业压力却没有缓解多少 很多粉丝后台留言 Java程序员面临的竞争太激烈了 我自己也有实感 多年身处一线互联网公司 虽没有直面过求职跳槽的残酷 但经常担任技术面试考官 对程序员招聘市场的现状很清楚 导致现
  • C++中.cpp和.hpp的区别

    时间 2020 06 02 标签 c cpp hpp 区别 栏目 C C 繁體版 原文 https my oschina net u 4398200 blog 3336507 原文地址 https blog csdn net qzx9059