.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++中头文件、源文件之间的区别与联系的更多相关文章

  1. C++中头文件与源文件的作用详解

    一.C++ 编译模式 通常,在一个 C++ 程序中,只包含两类文件―― .cpp 文件和 .h 文件.其中,.cpp 文件被称作 C++ 源文件,里面放的都是 C++ 的源代码:而 .h 文件则被称作 ...

  2. C语言中头文件怎么写?(本文来源网络,由黑乌鸦进一步完善)

      c语言头文件怎么写?我一直有这样的疑问,但是也一直没去问问到底咋回事:所以今天一定要把它弄明白! 其实学会写头文件之后可以为我们省去不少事情,可以避免书写大量的重复代码.有利于整理思路.使代码脉络 ...

  3. C/C++ 中头文件相互包含引发的问题

    转自:http://blog.csdn.net/hazir/article/details/38600419 今天下午遇到一个头文件相互包含而导致的编译问题,花了我不少时间去调试没找到问题,最后晚上跟 ...

  4. C++ 中头文件(.h)和源文件(.cc)的写法简述

    用C++编写比较大型的项目时,文件的分割管理确实确实是非常必要的 .下面就非常简洁明了地谈谈头文件(.h)和源文件(.cc)应该怎么写. 头文件(.h):写类的声明(包括类里面的成员和方法的声明).函 ...

  5. JavaScript中this和$(this)之间的区别以及extend的使用

    jQuery中this和$(this)之间的区别: this返回的是当前对象的html对象,而$(this)返回的是当前对象的jQuery对象 举个正确的Demo实例: $("#textbo ...

  6. VS 2010不显示头文件源文件和所有以前分类的文件夹,*.h 和*.cpp都显示在同一个文件

    打开VS后不显示头文件源文件和所有以前分类的文件夹,*.h 和*.cpp都显示在同一个文件 点击右图红色指示显示所有文件夹按钮,就能恢复.

  7. [转] C#中out和ref之间的区别

    gskcc 的原文地址 C#中out和ref之间的区别 首先:两者都是按地址传递的,使用后都将改变原来参数的数值. 其次:ref可以把参数的数值传递进函数,但是out是要把参数清空,就是说你无法把一个 ...

  8. c中头文件在cpp文件里引用和.h文件引用的思考

    我们在编敲代码中头文件是常常使用的. 可是头文件是应该包括在.H文件里还是在.cpp文件里.在这个其中有什么样去差别呢. 假如说我们编写了一个a.cpp  .我们将a.cpp文件的变量和函数申明在a. ...

  9. C语言中头文件尖括号和引号的区别

    用include 引用头文件时,双引号和尖括号的区别: 1.双引号:引用非标准库的头文件,编译器首先在程序源文件所在目录查找,如果未找到,则去系统默认目录查找,通常用于引用用户自定义的头文件. 2.尖 ...

随机推荐

  1. Python基础(14)_python模块之configparser模块、suprocess

    9.configparser模块 模块适用于配置文件的格式与windows ini文件类似,可以包含一个或多个节(section),每个节可以有多个参数(键=值). 常见的软件格式文档格式如下: [D ...

  2. SPOJ - HORRIBLE 【线段树】

    思路 线段树 区间更新 模板题 注意数据范围 AC代码 #include <cstdio> #include <cstring> #include <ctype.h> ...

  3. Python学习进程(7)字符串

        本节介绍字符串的创建与操作方法.     (1)创建字符串:     创建字符串既可以用单引号也可以用双引号: root@SJM:/home/sunjimeng/桌面# cat text.py ...

  4. OpenGL学习进程(2)OpenGL开发环境的搭建

        通过本节,我们来学习一下在Win10 64.VS1013环境下搭建OpenGL的开发环境.     (1)选择一个编译环境: 现在在windows中OpenGL的主流编译工具有Visual S ...

  5. yii常用操作函数

    <?php defined('YII_DEBUG') or define('YII_DEBUG', true); //当在调试模式下,应用会保留更多日志信息,如果抛出异常,会显示详细的错误调用堆 ...

  6. Django---Blog系统开发之建库

    数据库配置: #sqlite3数据库配置: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os. ...

  7. hdu1010感想

    杭电这道题是用dfs走迷宫问题,一直wa是因为没有将走过的地方标记,所以如果遇到走迷宫的问题一定要将走过的地方标记,如下: &&nx<n&&ny>=& ...

  8. java基础之bit、byte、char、String

    bit 位,二进制数据0或1 byte 字节,一个字节等于8位二进制数 char 字符, String 字符串,一串字符 常见转换 1 字母  = 1byte = 8 bit 1 汉字  = 2byt ...

  9. 关于C++ 中的this 的理解

    关键字this 通常被用在一个class内部,指正在被执行的该class的对象(object)在内存中的地址.它是一个指针,其值永远是自身object的地址.

  10. python 中文字符的处理

    刚开始学习python的时候,都是对这英文的翻译书学习的.没有解除到中文编码的相关问题,直到自己用python去做相关的项目的时候才发先中文编码问题真的非常头疼啊.这里分享一下本人所了解的一些经验. ...