EasyC++编写头文件
文章转自公众号:Coder梁(ID:Coder_LT)
我们之前做的左右示例都是在一个单独的cpp文件当中完成的,当我们要做一个相对复杂或大型的项目时,我们显然不能把所有代码都写在一个cpp里。这就需要我们拆分代码,但代码按照逻辑划分,写入不同的cpp文件当中。
在我们编译的时候,我们可以将这些cpp文件分别单独编译,最后再连接到一起。这样做的好处是,当我们只修改了某一个文件的时候,可以只用单独编译那一个文件,不会影响其他文件的编译结果。一般来说大型项目,都会使用一下自动化的编译工具,比如make
等,不会手动执行编译过程,但对于这其中的一些细节,还是需要有所了解。
我们来看C++ primer当中提供的一个例子。
现在我们要实现一个将直接坐标转化成极坐标的功能,我们需要定义两个结构体分别表示直角坐标和极坐标,另外还需要实现从直接坐标到极坐标的转化。
显然相对于主体程序而言,这部分代码是独立的,所以我们可以把它们放入一个单独的cpp文件当中。首先要明确的是,main()
函数和其他函数都用到了同一个结构体,因此两个cpp文件都需要包含该结构体的声明。显然拷贝代码是很糟糕的选择,比较好的做法是将结构体的声明写在头文件当中,通过#include
语句引入。
这样的话整体的代码就分成三个部分:
- 头文件:包含结构体声明、函数声明
coordin.cpp
:包含坐标系转化相关的代码main.cpp
:主体程序
在之后面向对象的章节当中, 我们将会经常用到这样的代码结构。
对于头文件当中的内容有严格的限制,由于头文件可能会被多个cpp文件引入,所以我们不能将函数的实现或参数的定义放入头文件当中。因为同一个程序中包含同一个函数的多个定义会引发报错,参数同理。
只有以下内容可以写入头文件当中:
- 函数原型(函数声明)
#define
或const
定义的符号常量- 结构体声明
- 类声明
- 模板声明
- 内联函数(
inline
)
在同一个文件当中只能引入一个头文件一次,但有的时候由于引用依赖的原因,可能会导致重复引入。比如引入A和B头文件,B头文件中引入了A,导致A被引入两次。
为了解决这个问题,我们可以加入预编译指令#ifndef
,含义是if not defined
,判断某定义是否存在。只有当定义不存在时才会直接#ifndef
和#endif
之间的语句:
#ifndef COORDIN_H_ // statements #endif
一般情况下我们使用#define创建符号常量:
#define MAXI 4096
但由于这里我们只是用来区分是否引入,所以只需要名称即可:
#ifndef COORDIN_H #define COORDIN_H // todo #endif
这样,当引入一次之后,COORDIN_H
即被定义,那么下次就不会再执行这段代码。
最后,我们写出完整的头文件代码:
#
ifndef COORDIN_H__ #define COORDIN_H__ struct polar { double distance, angle; }; struct rect { double x, y; }; polar rect_to_polar(rect xpros); void show_polar(polar dapos); #endif
到此这篇关于C++编写头文件的文章就介绍到这了,更多相关C++编写头文件内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
相关推荐
-
EasyC++单独编译
文章转自:微信公众号:Coder梁(ID:Coder_LT) 联合编译: 在上一篇当中,我们编写好了头文件coordin.h,现在我们要完成它的实现 头文件当中只能放一些生命和常量的定义,不能有具体的实现.所以我们要把具体的实现单独放入一个cpp文件当中.因为我们的头文件叫做coordin.h,那么我们与之对应的cpp文件自然就叫做coordin.cpp. 在coordin.h当中我们声明了两个函数,自然我们就要完成这两个函数的实现: #include <cstdio> #include &l
-
C++模板重载
目录 1.重载模板 2.问题 文章转自 公众号:Coder梁(ID:Coder_LT) 1.重载模板 函数模板可以使得同一个函数对不同类型使用,非常地方便.但有的时候类型不同,只是通过模板是没办法解决的, 可能逻辑上也会有所区别,这个时候只是使用模板是无法解决的. 为了满足这种需求,我们可以像是重载函数那样重载模板.和常规的函数一样,重载的模板的函数特征,也就是入参的数量和类型必须有所不同. 举个例子:比如我们之前定义了一个函数模板用来交换两个变量的值.如果我们要交换的不只是变量,而是两个数组
-
详解C++中的自动存储
C++有3种管理数据内存的方式即自动存储(栈存储).静态存储和动态存储(堆存储).在不同的方式下,内存的分配形式和存在时间的长短都不同. 下面对自动存储进行说明. 自动存储(栈存储) 对于函数的形参.内部声明的变量及结构变量等,编译器将在函数执行时为形参自动分配存储空间,在执行到变量和结构变量等的声明语句时为其自动分配存储空间,因此称其为自动变量(Automatic Variable),有的教科书也称其为局部变量,在函数执行完毕返回时,这些变量将被撤销,对应的内存空间将被释放. 事实上,自动变量
-
EasyC++自动存储持续性
转自微信公众号:Coder梁(ID:Coder_LT) 自动存储持续性: 这个概念乍一看有些拗口,其实它很简单,指的是在函数定义中声明的变量的存储持续性是自动的:它们在程序开始执行其所属的函数或代码块时被创建,在执行完函数或代码块时,它们使用的内存被释放. 在默认情况下,我们在函数中声明的变量和函数的参数都是自动存储持续性,它的作用于为局部,没有链接性. 这里的链接性描述了名称如何在不同的单元之间共享,链接性为外部的名称可以在文件之间共享,链接性为内部的名称只能由一个车文件中的函数共享.自动变量
-
C++函数模板介绍
文章转自: 公众号:Coder梁(ID:Coder_LT) 函数模板: 所谓函数的模板,本质上也就是使用泛型来定义函数. 所谓的泛型其实也就是不定的类型,比如说我们使用vector的时候,可以定义各种类型的vector,可以定义存储int型的vector也可以定义存储float类型的,也可以定义存储其他类型.我们在声明的时候将存储的类型当做参数传给了模板. 泛型可以用具体的类型,比如(int或double)替换,通过将类型作为参数传给模板,编译器会根据传递的参数类型生成该类型的函数.这种方式也被
-
C++ 右值引用
目录 1.左值和右值 2.左值引用和右值引用 文章转自:公众号:Coder梁(ID:Coder_LT) 1.左值和右值 在我们之前的文章当中,介绍的都是左值引用.C++11在左值引用的基础上推出了右值引用,由于是新特性,加上使用的频率也不是很高,有一定的学习成本. 我们先把引用这个概念抛开,先来看看什么是左值什么是右值.其实很简单,左值可以取地址,位于等于号的左侧.而右值没办法取地址,位于等于号的右侧. int a = 4; 比如我们定义了一个int型的变量a,让它的值等于4.其中a位于等于号的
-
C++模板显式具体化
出品 | 公众号:Coder梁(ID:Coder_LT) 前文当中说了,模板函数虽然非常好用,但是也存在一些问题.比如有的操作并不是对所有类型都适用的,针对这种情况C++提供了一个解决方案,就是针对特定类型提供具体化的模板定义.这里的具体可以理解成类型的具体. 我们来看一个C++ Primer当中的例子,假设现在我们有一个结构体叫做job: struct job { string name; double salary; int floor; } 对于结构体是可以整体赋值的,所以之前的Swap函
-
EasyC++编写头文件
文章转自公众号:Coder梁(ID:Coder_LT) 我们之前做的左右示例都是在一个单独的cpp文件当中完成的,当我们要做一个相对复杂或大型的项目时,我们显然不能把所有代码都写在一个cpp里.这就需要我们拆分代码,但代码按照逻辑划分,写入不同的cpp文件当中. 在我们编译的时候,我们可以将这些cpp文件分别单独编译,最后再连接到一起.这样做的好处是,当我们只修改了某一个文件的时候,可以只用单独编译那一个文件,不会影响其他文件的编译结果.一般来说大型项目,都会使用一下自动化的编译工具,比如mak
-
C++编写头文件
文章转自公众号:Coder梁(ID:Coder_LT) 我们之前做的左右示例都是在一个单独的cpp文件当中完成的,当我们要做一个相对复杂或大型的项目时,我们显然不能把所有代码都写在一个cpp里.这就需要我们拆分代码,但代码按照逻辑划分,写入不同的cpp文件当中. 在我们编译的时候,我们可以将这些cpp文件分别单独编译,最后再连接到一起.这样做的好处是,当我们只修改了某一个文件的时候,可以只用单独编译那一个文件,不会影响其他文件的编译结果.一般来说大型项目,都会使用一下自动化的编译工具,比如mak
-
C++中头文件的概念与基本编写方法
1 标准库中的头文件 C++标准库中的一切内容都被放在名字空间std中(名字空间中的内容对外是不可见的),但是带来了一个新问题,无数现有的C++代码都依赖于使用了多年的伪标准库中的功能,如声明在<iostream.h>等头文件中的功能,使用std包装标准库导致现有代码的不可用,为了兼容这种情况,标准委员会为包装了std的那部分标准库创建了新的头文件,新的头文件的文件名与旧的一样,只是没有.h这个后缀,如<iostream.h>就变成了<iostream>.对于C头文件,
-
C++中头文件和源文件详细介绍
C++中的头文件和源文件详解 一.C++编译模式 通常,在一个C++程序中,只包含两类文件--.cpp文件和.h文件.其中,.cpp文件被称作C++源文件,里面放的都是C++的源代码:而.h文件则被称作C++头文件,里面放的也是C++的源代码. C+ +语言支持"分别编译"(separate compilation).也就是说,一个程序所有的内容,可以分成不同的部分分别放在不同的.cpp文件里..cpp文件里的东西都是相对独立的,在编 译(compile)时不需要与其他文件互通,只需要
-
linux下socket编程常用头文件(推荐)
sys/types.h:数据类型定义 sys/socket.h:提供socket函数及数据结构 netinet/in.h:定义数据结构sockaddr_in arpa/inet.h:提供IP地址转换函数 netdb.h:提供设置及获取域名的函数 sys/ioctl.h:提供对I/O控制的函数 sys/poll.h:提供socket等待测试机制的函数 其他在网络程序中常见的头文件 unistd.h:提供通用的文件.目录.程序及进程操作的函数 errno.h:提供错误号errno的定义,用于错误处理
-
C语言编程入门之程序头文件的简要解析
头文件是扩展名为.h的文件,其中包含C函数的声明和宏定义,也可以多个源文件之间共享.有两种类型的头文件:程序员编写的文件,和编译器中附带的文件. 要求使用头文件的程序,包括通过它,使用C语言预处理指令#include就像所看到的包含stdio.h头文件,它随着编译器自带. 包括一个头文件等于复制头文件的内容,但我们不这样做,因为这很容易出错,一个好主意是我们不复制头文件的内容,特别是包括多个程序的源文件. 在C或C++程序的简单做法是,我们把所有的常量,宏全系统全局变量和函数原型在头文件,其中包
-
C++的头文件和实现文件详解
在C++编程过程中,随着项目的越来越大,代码也会越来越多,并且难以管理和分析.于是,在C++中就要分出了头(.h)文件和实现(.cpp)文件,并且也有了Package的概念. 对于以C起步,C#作为"母语"的我刚开始跟着导师学习C++对这方面还是感到很模糊.虽然我可以以C的知识面对C++的语法规范,用C#的思想领悟C++中类的使用.但是C#中定义和实现是都在一个文件中(其实都是在类里面),而使用C的时候也只是编程的刚刚起步,所写的程序也只要一个文件就够了.因此对于C++的Package
-
C++中头文件与源文件的作用详解
一.C++ 编译模式 通常,在一个 C++ 程序中,只包含两类文件-- .cpp 文件和 .h 文件.其中,.cpp 文件被称作 C++ 源文件,里面放的都是 C++ 的源代码:而 .h 文件则被称作 C++ 头文件,里面放的也是 C++ 的源代码. C++ 语言支持"分别编译"(separatecompilation).也就是说,一个程序所有的内容,可以分成不同的部分分别放在不同的 .cpp 文件里..cpp 文件里的东西都是相对独立的,在编译(compile)时不需要与其他文件互通
-
VScode编译C++ 头文件显示not found的问题
一直用codeblocks,想试试vscode,结果这个问题给我弄懵逼了.一开始以为是iostream这个头文件not found,后来发现第一个头文件都会这样显示,放到后面就不会了,然而,光这一个显示not found(虽然并不影响编译),就能逼死强迫症的啊~~~ 言归正传,这个问题解决方法是: 文件--首选项--设置--搜索"clang.diagnostic.enable",然后把勾勾去掉就好了.这是插件C/C++ Clang Command Adapter的一个选项~~ 如果一堆
-
VS2019如何添加头文件路径的方法步骤
大家在编写程序的时候往往会创建许多头文件,那么在VS2019中我们该怎么调用自己创建的头文件呢,其实只需要将头文件的路径添加到工程的编译环境中就行了,下面就来看看吧! 1.点击项目->属性->C/C+±>常规->附加包含路径,将路径添加进去. 最后再单击确定,就成功将自制的头文件路径添加成功啦! VS2019中设置了头文件路径却提示找不到头文件的一种原因 最近在设置VS2019工程中头文件的时候,出现一个很奇怪的问题:明明设置了头文件的附加包含目录,但是仍然提示头文件找不到.一种原
随机推荐
- JavaScript+CSS相册特效实例代码
- Linux IO的水平触发和边缘触发的区别
- DB2编程序技巧 (五)
- jQuery提交表单ajax查询实例代码
- Go语言hello world实例
- socks5代理的使用以及ftp多线程下载的简易方法
- JavaScript操作DOM元素的childNodes和children区别
- asp.net GridView排序简单实现
- mysql中如何去除小数点后面多余的0
- 在Mac OS X安装Docker教程
- Android实现标题显示隐藏功能
- php代码把全角数字转为半角数字
- javascript连续赋值问题
- HTML的select控件美化
- Oracle数据库账号被锁定解决方法
- 原生js实现轮播图
- 怎么限制input的text里输入的值只能是数字(正则、js)
- 解读vue生成的文件目录结构及说明
- 从零开始封装自己的自定义Vue组件
- 图解javascript作用域链