C++中头文件、源文件之间的区别与联系
.h头文件和.cpp文件的区别
疑惑1:.h文件能够编写main函数吗?
实验:
编写test.h文件,里面包含main函数
若直接编译g++ test.h -o test,通过file命令 file test,得到如下结果test: GCC precompiled header (version ) for C++ ———test文件是预编译头文件 推测:.h文件不能单独生成.o文件 疑惑2:.h文件中声明和定义的变量和函数是如何与.cpp文件结合的?
实验:
编写test.h文件,里面包含一个变量定义以及函数定义,编写test.cpp文件包含该头文件,通过g++ -E test.cpp -o test.i生成预编译文件,打开test.i文件发现,上面包含了头文件中变量的定义以及函数的定义,就像平时我们可以不写.h文件,只写.cpp文件一样,把所有的声明和定义都放在了一个.cpp文件中。 test.h
#ifndef _TEST_H
#define _TEST_H
int var = ;
void func {
}
#endif
test2.h
#ifndef _TEST2_H
#define _TEST2_H
#include "test.h"
#endif
test.cpp
#include "test.h"
#include "test2.h"
int main ()
{
var = ;
return ;
}
gcc -E test.cpp -o test.i 得到test.i预编译文件 # "test.cpp"
# "<built-in>"
# "<command line>"
# "test.cpp"
# "test.h"
int var = ;
void func {
}
# "test.cpp"
# "test2.h"
# "test.cpp"
int main ()
{
var = ;
return ;
} 推测:.cpp文件中的#include预编译指令将.h的文件内容包含进来(#include指令是递归执行的),并通过条件预编译指令#ifndef、#define、#endif将重复的.h头文件去除,否则会在编译过程中出现重定义错误。 一些思考:
、.h头文件的作用只出现在预编译阶段,预编译后.h文件就失去了价值,也就是说一个.cpp文件为一个编译单元,一个.cpp文件最终生成一个.o文件
、.h头文件应该包含些什么?
a. 包含声明、条件预编译指令以及类的定义(类的定义一定要有条件预编译指令,否则多个文件包含会出现重定义错误)
b. 包含需要的的头文件,无关的头文件都不需要包含,cpp使用的头文件都放入cpp文件中,或者单独建立一个总体的头文件包含所有需要使用的头文件
c. 包含常量(包括const常量声明,定义放在源文件中)和宏定义 在头文件中定义变量或函数会出现什么问题?(全局变量和函数默认是extern属性) local_comm.h #ifndef _LOCAL_H
#define _LOCAL_H
int var = ;
void func() {};
#endif
test1.cpp #include <stdio.h>
#include "local_comm.h" void func1()
{
printf("func1 &var=%lu\n", &var);
}
test2.cpp #include <stdio.h>
#include "local_comm.h" void func2()
{
printf("func2 &var=%lu\n", &var);
}
main.cpp extern void func1();
extern void func2();
int main()
{
func1();
func2();
}
g++ main.cpp test1.cpp test2.cpp 编译报错
$g++ main.cpp test1.cpp test2.cpp
/tmp/ccGkEzQE.o: In function `func()':
test2.cpp:(.text+0x0): multiple definition of `func()'
/tmp/ccpTecbJ.o:test1.cpp:(.text+0x0): first defined here
/tmp/ccGkEzQE.o:(.data+0x0): multiple definition of `var'
/tmp/ccpTecbJ.o:(.data+0x0): first defined here
collect2: ld returned exit status 结论:头文件的条件预编译指令只能去掉同一个编译单元中包含的重复定义,不能在链接的时候去掉各个编译单元中的相同的定义,因为普通变量和函数默认属性是全局的,也就是在整个最后生成的exe中只能有唯一一个同名的变量和函数。 在头文件中定义static静态变量或者静态函数会出现什么问题?(全局const变量默认是static属性) 修改local_comm.h,将变量和函数改成static属性。 #ifndef _LOCAL_H
#define _LOCAL_H
static int var = ;
static void func() {};
#endif
编译运行: $g++ main.cpp test1.cpp test2.cpp
$./a.out
func1 &var=
func2 &var= 结论:静态变量和静态函数的作用域只是在本编译单元(.o文件),在不同的副本都保存了该静态变量和静态函数,正是因为static有以上的特性,所以一般定义static全局变量时,都把它放在原文件中而不是头文件,这样就不会给其他模块造成不必要的信息污染。 转:http://my.oschina.net/fergus/blog/123484
C++中头文件、源文件之间的区别与联系的更多相关文章
- C++中头文件与源文件的作用详解
一.C++ 编译模式 通常,在一个 C++ 程序中,只包含两类文件―― .cpp 文件和 .h 文件.其中,.cpp 文件被称作 C++ 源文件,里面放的都是 C++ 的源代码:而 .h 文件则被称作 ...
- C语言中头文件怎么写?(本文来源网络,由黑乌鸦进一步完善)
c语言头文件怎么写?我一直有这样的疑问,但是也一直没去问问到底咋回事:所以今天一定要把它弄明白! 其实学会写头文件之后可以为我们省去不少事情,可以避免书写大量的重复代码.有利于整理思路.使代码脉络 ...
- C/C++ 中头文件相互包含引发的问题
转自:http://blog.csdn.net/hazir/article/details/38600419 今天下午遇到一个头文件相互包含而导致的编译问题,花了我不少时间去调试没找到问题,最后晚上跟 ...
- C++ 中头文件(.h)和源文件(.cc)的写法简述
用C++编写比较大型的项目时,文件的分割管理确实确实是非常必要的 .下面就非常简洁明了地谈谈头文件(.h)和源文件(.cc)应该怎么写. 头文件(.h):写类的声明(包括类里面的成员和方法的声明).函 ...
- JavaScript中this和$(this)之间的区别以及extend的使用
jQuery中this和$(this)之间的区别: this返回的是当前对象的html对象,而$(this)返回的是当前对象的jQuery对象 举个正确的Demo实例: $("#textbo ...
- VS 2010不显示头文件源文件和所有以前分类的文件夹,*.h 和*.cpp都显示在同一个文件
打开VS后不显示头文件源文件和所有以前分类的文件夹,*.h 和*.cpp都显示在同一个文件 点击右图红色指示显示所有文件夹按钮,就能恢复.
- [转] C#中out和ref之间的区别
gskcc 的原文地址 C#中out和ref之间的区别 首先:两者都是按地址传递的,使用后都将改变原来参数的数值. 其次:ref可以把参数的数值传递进函数,但是out是要把参数清空,就是说你无法把一个 ...
- c中头文件在cpp文件里引用和.h文件引用的思考
我们在编敲代码中头文件是常常使用的. 可是头文件是应该包括在.H文件里还是在.cpp文件里.在这个其中有什么样去差别呢. 假如说我们编写了一个a.cpp .我们将a.cpp文件的变量和函数申明在a. ...
- C语言中头文件尖括号和引号的区别
用include 引用头文件时,双引号和尖括号的区别: 1.双引号:引用非标准库的头文件,编译器首先在程序源文件所在目录查找,如果未找到,则去系统默认目录查找,通常用于引用用户自定义的头文件. 2.尖 ...
随机推荐
- 两张Excel表比较,两个for循环比较优化使用Contains
将一个Excel表中的sheet中的一列导出到List<string>,用一个for循环循环另一张表中的数据,看是否在第一张表中的Contains中
- 曾经跳过的坑----js截取字符串substr与substring 和 trim
不废话直接代码.自己理解...... > "abcdefg".substring(1,6)> "bcdef"> "abcdefg&q ...
- iOS URL Loading System / HTTP 重定向 认识与学习
一个朋友问了我一个问题,需求是这样的:他要用本地的H5资源 替换 链接资源, 但是判断链接资源时候 因为一些操作请求本地化了之后 一些操作比如请求服务器使用的是http开头,然而本地资源一直是以f ...
- 建议37:按需选择sort或sorted
# -*- coding:utf-8 -*- ''' 用法: sorted(iterable[, cmp[, key[, reverse]]]) s.sort([cmp[, key[, reverse ...
- 【Tech】mac下svn和scp使用笔记
1.命令行从svn下载代码 mac本身自带svn,所以使用非常简单,在本地创建代码存放的文件夹,然后cd到该文件夹下,运行: svn checkout svn://ip地址/文件路径 . 然后出现要求 ...
- android 获取视频缩略图终极解决方案(ffmpeg)
http://blog.csdn.net/u010499721/article/details/50338623 前些天有个师弟(在做一个仿LinkInEyes行车记录仪的app)问我怎么获取视频缩略 ...
- 主攻ASP.NET.4.5.1 MVC5.0之重生:在项目中使用zTree jQuery 树插件
效果图和json格式 Controllers代码 using HR.Models; using HR.Models.Repository; /***************************** ...
- PHP 最大化资源配置 Resource Limits 错误两则
报错信息1:PHP Fatal error: Allowed memory size of 25165824 bytes exhausted (tried to allocate 67108888 b ...
- NSFetchedResultController与UITableView
1 #import "AppDelegate.h" #import "Book.h" @interface AppDelegate () @end @imple ...
- FTH: (7156): *** Fault tolerant heap shim applied to current process. This is usually due to previous crashes. ***
这两天在Qtcreator上编译程序的时候莫名其妙的出现了FTH: (7156): *** Fault tolerant heap shim applied to current process. T ...