在使用C++进行程序开发的时候,有个常识我们很熟悉,就是把类的定义写在.h文件中,把类的具体实现写在.cpp文件中。这毫无疑问是对的。但我们很少去思考为什么要这样做,本文结合自己的学习体会,对头文件及const对象的定义进行一些说明。

1。为什么要使用头文件

使用头文件就是为了在希望使用一些共同函数或数据的时候,只需包含这个文件就能实现,无需多次重复编写相同的代码,提高了效率。

2。什么东西可以写在头文件中

在头文件中,我们的编程经验是,函数的声明,类的定义等等应该写在头文件里面。但具体哪些可以写,哪些不可以,并不十分清楚。

在C++程序中,我们可以知道对于变量或函数的定义是唯一的,如果在同一个作用域内有重复的定义,就会产生编译错误。而头文件是要被多个文件包含的,如果在头文件中存放变量或函数的定义,则会导致编译提示重定义这样的错误,而声明则是可以多处编写的,所以,通过程序的基本知识,头文件中应该写声明,而不能写定义。

3。例外的情况

但我们确实在实践中有定义放在头文件中,而且并不引发编译错误,难道定义可以放在头文件中吗,C++允许部分重定义吗?

C++中允许在头文件中定义的有三中情况:

(1)类定义

(2)内联函数定义(inline函数。在头文件中有函数实现的,默认为内联函数)

(3)const 对象定义

其实以上三种情况的原因可以理解为是相同的。以const对象作为例子,说明如下:

对于一般的对象 如 int a=9;;

我们知道它的作用域是整个程序的,在1.cpp和2.cpp中包含同一个定义了int a=9;的头文件,因为int a=9;作用域是整个程序,所以会产生错误。那为什么const int a=9;不会产生错误呢。原因就是const int a=9;的默认作用范围是文件作用域的。即,尽管在1.cpp和2.cpp中包含同一个定义了const int a=9;的头文件,但由于const int a=9;是文件作用域的,包含了头文件的1.cpp和2.cpp尽管都包含了const int a=9;但他们是各自文件内的const对象,两者互不相干,就像不同函数中定义了相同的变量名一样。

所以,通过在头文件中定义const对象,可以实现多个文件使用相同的常量值,这在实际的程序中很常见。

说到这里,有一点疑问需要解决:如果想在别的文件中访问本文件中的const对象该怎么办,如果都是单是在别的文件中使用extern const int a = 9;的话,不会起任何作用,因为已经提示const int a = 9;是文件作用域的。所以应该在需要被其他文件使用的const对象定义成这样:extern const int a = 9;而在别的需要使用这个const对象的地方使用:extern const int a;前者是定义,后者是声明。这样就可以使用了。

通过对const对象的说明,我们知道由于是文件作用域的原因,可以把const对象的定义写在头文件中。对于另外两种情况,从实践上来看,我觉得也可以认为他们具有文件作用域。

比如在同一个文件中,编写两个完全相同的类的定义,编译会提示重定义错误,但在两个不同的文件中,编写完全相同的类的定义,不会导致编译错误,这说明类的作用域也是文件作用域,在包含了同一个头文件的不同文件中,虽然都包含了同一个类的定义,但程序理解为是两个不同的类的定义(尽管结构完全相同),但这在实现上没有问题。当然,关于inline函数也可以这样理解,具体原因可能需要查看编译器的相关资料。

c++中const变量定义与头文件包含的有关问题的更多相关文章

  1. GCC 环境变量 & eclipse CDT 头文件配置

     转:http://blog.csdn.net/statdm/article/details/7751000 GCC 环境变量 & eclipse CDT 头文件配置   在unix 下使用e ...

  2. VC++中的头文件包含问题

    在一些大的工程中,可能会包含几十个基础类,免不了之间会互相引用(不满足继承关系,而是组合关系).也就是需要互相声明.好了,这时候会带来一些混乱.如果处理得不好,会搞得一团糟,根据我的经验,简单谈谈自已 ...

  3. Effective Objective-C 2.0 — 第二条:类的头文件中尽量少引入其他头文件

    第二条:类的头文件中尽量少引入其他头文件 使用向前声明(forward declaring) @class EOCEmployer 1, 将引入头文件的实际尽量延后,只在确有需要时才引入,这样就可以减 ...

  4. C++ 中的模板类声明头文件和实现文件分离后,如何能实现正常编译?

    C++ 中的模板类声明头文件和实现文件分离后,如何能实现正常编译? 这个feature叫做Export Template,即外名模板,它的作用在于使得模板代码可依照C/C++语言习惯,将模板声明和实现 ...

  5. error C2504 类的多层继承 头文件包含

    error C2504:头文件包含不全 今天碰到了很烦的问题,继承一个类之后,感觉头文件都包含了,可还是出现父类未定义的问题,最后发现,子类的子类在实现时,需要在cpp文件中包含所有他的父类的定义.因 ...

  6. c++ 头文件包含问题-include&class

    http://blog.csdn.net/jiajia4336/article/details/8996254 前向声明概念(forward declaration) 在程序中引入了类类型的B.在声明 ...

  7. ZT 头文件包含其实是一想很烦琐的工作 第一个原则应该是,如果可以不包含头文件

    当出现访问类的函数或者需要确定类大小的时候,才需要用头文件(使用其类定义)    http://blog.csdn.net/clever101/article/details/4751717 看到这个 ...

  8. c++头文件包含 #ifndef ##pragma once

    2013-04-14 17:03 (分类:计算机程序) 烦死了,这种垃圾小问题很多,你又必须要知道.......在编写c++程序时,会编写多个类或者多个cpp文件,免不了要多次使用include包含头 ...

  9. VS2008引入头文件包含目录和lib库目录

    全局级别的引入 为VS所有项目设置包含目录和库目录,对所有项目都有效 如下图所示:工具-选项-项目和解决方案-VC++目录-包含文件:在此添加头文件目录即可 工具-选项-项目和解决方案-VC++目录- ...

随机推荐

  1. 2017-9-15Opencv 杂

    Mat::at()的具体含义.指的是三通道.(0),(1),(2)分别表示BGR: Vector<Mat>结构的使用.将Mat类型的数据转化成了具有多个单通道的容器? 灰度图的具体含义.和 ...

  2. CSS-使用CSS样式的方式

    1.HTML<!DOCTYPE>声明标签 (1)定义和用法 <!DOCTYPE>声明必须是HTML文档的第一行,位于<html>标签之前. <!DOCTYPE ...

  3. BZOJ-2424: [HAOI2010]订货【费用流】

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1487  Solved: 1002[Submit][Status][Discuss] Descript ...

  4. LeetCode136. 只出现一次的数字(异或)

    给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找出那个只出现了一次的元素. 说明: 你的算法应该具有线性时间复杂度. 你可以不使用额外空间来实现吗? 示例 1: 输入: [ ...

  5. spring boot no identifier specified for entity

    定义Id 时,引用的是 import org.springframework.data.annotation.Id;  实际应该引入: import javax.persistence.Id;

  6. Hadoop 集群ssh免密登录设置

    0.安装命令: yum list installed | grep openssh-server 命令检查ssh安装有没有安装,如果查询出来有就表示安装了,否则反之 通过 yum install op ...

  7. layui树形结构更改

    /* * 将json字符串更改为layui.tree所用的数据结构类型,输出仍然为json字符串 * tanghao 7.29 */ function dataToTreeData(oData_str ...

  8. 【转载】JS导出CSV文件

    转自:http://www.cnblogs.com/dengnan/p/3990211.html 通过自己实际测试有以下几种方法 方法一通过a标签实现,把要导出的数据用“\n”和“,”拼接成一个字符串 ...

  9. python面试的100题(15)

    41.super函数的具体用法和场景 为了调用父类(超类)的一个方法,可以使用 super() 函数,比如: class A: def spam(self): print('A.spam') clas ...

  10. JUC—Callable接口

    一.callable接口是什么? 面试题: 获得多线程的方法几种? 正确答案如下: 传统的 是继承thread类和实现runnable接口, java5以后又有实现 callable接口 和 java ...