c++中const变量定义与头文件包含的有关问题
在使用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变量定义与头文件包含的有关问题的更多相关文章
- GCC 环境变量 & eclipse CDT 头文件配置
转:http://blog.csdn.net/statdm/article/details/7751000 GCC 环境变量 & eclipse CDT 头文件配置 在unix 下使用e ...
- VC++中的头文件包含问题
在一些大的工程中,可能会包含几十个基础类,免不了之间会互相引用(不满足继承关系,而是组合关系).也就是需要互相声明.好了,这时候会带来一些混乱.如果处理得不好,会搞得一团糟,根据我的经验,简单谈谈自已 ...
- Effective Objective-C 2.0 — 第二条:类的头文件中尽量少引入其他头文件
第二条:类的头文件中尽量少引入其他头文件 使用向前声明(forward declaring) @class EOCEmployer 1, 将引入头文件的实际尽量延后,只在确有需要时才引入,这样就可以减 ...
- C++ 中的模板类声明头文件和实现文件分离后,如何能实现正常编译?
C++ 中的模板类声明头文件和实现文件分离后,如何能实现正常编译? 这个feature叫做Export Template,即外名模板,它的作用在于使得模板代码可依照C/C++语言习惯,将模板声明和实现 ...
- error C2504 类的多层继承 头文件包含
error C2504:头文件包含不全 今天碰到了很烦的问题,继承一个类之后,感觉头文件都包含了,可还是出现父类未定义的问题,最后发现,子类的子类在实现时,需要在cpp文件中包含所有他的父类的定义.因 ...
- c++ 头文件包含问题-include&class
http://blog.csdn.net/jiajia4336/article/details/8996254 前向声明概念(forward declaration) 在程序中引入了类类型的B.在声明 ...
- ZT 头文件包含其实是一想很烦琐的工作 第一个原则应该是,如果可以不包含头文件
当出现访问类的函数或者需要确定类大小的时候,才需要用头文件(使用其类定义) http://blog.csdn.net/clever101/article/details/4751717 看到这个 ...
- c++头文件包含 #ifndef ##pragma once
2013-04-14 17:03 (分类:计算机程序) 烦死了,这种垃圾小问题很多,你又必须要知道.......在编写c++程序时,会编写多个类或者多个cpp文件,免不了要多次使用include包含头 ...
- VS2008引入头文件包含目录和lib库目录
全局级别的引入 为VS所有项目设置包含目录和库目录,对所有项目都有效 如下图所示:工具-选项-项目和解决方案-VC++目录-包含文件:在此添加头文件目录即可 工具-选项-项目和解决方案-VC++目录- ...
随机推荐
- 二叉堆(1)BinaryHeap
封装一个简单二叉堆,亦可视为优先队列. 测试文件 main.cpp: #include <iostream> #include "BinaryHeap.h" using ...
- 使用vim打开文件的16进制形式,编辑和全文替换
1.先用vim打开文件的二进制形式,如果不以二进制可能会产生转换错误. vim -b file-to-open.dat 2.用xxd把文件转换成十六进制格式 :%!xxd 现在就可以对待普通文本一样查 ...
- centos7 配置mailx使用外部smtp发送外网邮件
1- 安装 1.1- 安装mailx yum install mailx -y 2- 配置 2.1- 配置外部发件邮箱 vim /etc/mail.rc 在最后加上: //如果不存在,则编辑/etc/ ...
- java - CAS及CAS底层原理
CAS是什么? CAS的全称为Compare-And-Swap它是一条CPU并发原语,也就是在CPU硬件层面上来说比较并且判断是否设置新值这段操作是原子性的,不会被其他线程所打断.在JAVA并发包ja ...
- 2017-9-15Opencv 杂
Mat::at()的具体含义.指的是三通道.(0),(1),(2)分别表示BGR: Vector<Mat>结构的使用.将Mat类型的数据转化成了具有多个单通道的容器? 灰度图的具体含义.和 ...
- pytest-pytest-html生成HTML测试报告
pytest-HTML是一个插件,pytest用于生成测试结果的HTML报告.兼容Python 2.7,3.6 pytest-html 1.github上源码地址[https://github.com ...
- LaTeX技巧002:\section{}章节命令添加中文编译不了问题
在宏包hyperref前面添加选项CJKbookmarks \usepackage[CJKbookmarks]{hyperref} 并且把这句话尽可能地加在导言区的最底部,即尽可能靠近 \begin{ ...
- 如何在macOS下安装geoserver
macOS 下的编译包 如果是使用安装文件,请查看官网文档,如果想要部署在已有的tomcat服务下,请查看网页压缩包章节. Web archive. An alternate way of insta ...
- C++——浅拷贝
10.深拷贝与浅拷贝 浅拷贝: 实现对象间数据元素的一一对应赋值:(默认构造函数) 深拷贝: 当被复制的对象数据成员是指针类型时,不是复制该指针成员本身,而是将指针所指的对象进行复制. //浅拷贝 # ...
- CSS的快速入门
CSS的快速入门 1.CSS要学习的内容主要包括 1. CSS概念和快速入门 2.CSS选择器(重点+难点) 3.美化网页(文字.阴影.超链接.列表.渐变,等) 4.盒子模型 5.浮动 6.定位 2. ...