C++中extern关键字用法小结

摘要:
总结C++中关于extern关键字的用法。一个显式实例化具有如下形式:externtemplatedeclaration;//实例化声明templatedeclaration;//实例化定义declaration是一个类或函数的声明,其中所有的模板参数都已经被替换成为模板实参。对于一个给定的实例化版本,可能有多个extern声明,但必须只有一个定义。由于编译器在使用一个模板时自动对其实例化,因此extern声明必须出现在任何使用此实例化吧版本的代码之前。由于以上讨论可知:extern一般是使用在多文件之间需要共享某些代码时。

总结C++中关于extern关键字的用法。

1.变量的生明和定义中

C++语言支持分离式编译机制,该机制允许将程序分割为若干个文件,每个文件可被独立编译。为了将程序分为许多文件,则需要在文件中共享代码,例如一个文件的代码可能需要另一个文件中中定义的变量。

为了支持分离式编译,C++允许将声明和定义分离开来。变量的声明规定了变量的类型和名字,即使一个名字为程序所知,一个文件如果想使用别处定义的名字则必须包含对那个名字的声明。定义则负责创建与名字关联的实体,定义还申请存储空间。

如果想声明一个变量而非定义它,就在变量名前添加extern关键字,而且不要显式地初始化变量:

extern int i;  //声明i而非定义
int j;         //声明并定义i

但我们也可以给由extern关键字标记的变量赋一个初始值,但这样就不是一个声明了,而是一个定义:

extern int v = 2;
int v = 2;     //这两个语句效果完全一样,都是v的定义

注意: 变量能且只能被定义一次,但是可以被声明多次。

2.在多个文件中共享const对象

默认情况下,一个const对象仅在本文件内有效,如果多个文件中出现了同名的const变量时,其实等同于在不同的文件中分别定义了独立的变量。

某些时候有这样一种const变量,它的初始值不是一个常量表达式,但又确实有必要在文件间共享。这种情况下,我们不希望编译器为每个文件分别生成独立的变量。我们想让这类const对象像其他非常量对象一样工作,也就是说,只在一个文件中定义const,而在其他多个文件中声明并使用它。

方法是对于const变量不管是声明还是定义都添加extern关键字,这样只需要定义一次就可以了:

//file1.cpp定义并初始化和一个常量,该常量能被其他文件访问
extern const int bufferSize = function();
//file1.h头文件
extern const int bufferSize; //与file1.cpp中定义的是同一个

file1.h头文件中的声明也由extern做了限定,其作用是指明bufferSize并非本文件独有,它的定义将出现在别处。

3.模板的控制实例化

当两个或者多个独立编译的源文件中使用了相同的模板并且提供了相同的模板参数时,每个文件中都会有该模板的一个实例。

在大系统中,在多个文件中实例化相同的模板的额外开销可能非常严重,在C++11新标准中,我们可以通过显式实例化来避免这种开销。一个显式实例化具有如下形式:

extern template declaration; //实例化声明
template declaration;        //实例化定义

declaration是一个类或函数的声明,其中所有的模板参数都已经被替换成为模板实参。例如:

extern template class vec<string>;       //声明
template int sum(const int, const int);  //定义

当编译器遇到extern模板声明时,它不会在本文件中生成实例化代码,将一个实例化声明为extern就表示承诺在程序的其他位置有该实例化的一个非extern定义。对于一个给定的实例化版本,可能有多个extern声明,但必须只有一个定义。

由于编译器在使用一个模板时自动对其实例化,因此extern声明必须出现在任何使用此实例化吧版本的代码之前。

由于以上讨论可知:extern一般是使用在多文件之间需要共享某些代码时。

免责声明:文章转载自《C++中extern关键字用法小结》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇关于使用JQ scrollTop方法进行滚动定位黑马程序员——JAVA学习笔记六(多线程)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C# new和初始化

虽然知道使用new可以创建对象,但一直不是很理解初始化和new等知识的具体。 通过8个问题和需求,了解相关知识。 了解问题和需求 1.new 的三个步骤 2.初始化是什么意思。 3.变量声明后和变量赋值为null或变量调用了new的区别。 4.字段不是变量。 一、new的三个步骤: 1 在栈或者堆中开辟空间,空间的大小由类决定,进行内存空间指向。 2 在开...

C++解析(28):异常处理

0.目录 1.C语言异常处理 2.C++中的异常处理 3.小结 1.C语言异常处理 异常的概念: 程序在运行过程中可能产生异常 异常(Exception)与 Bug 的区别 异常是程序运行时可预料的执行分支 Bug 是程序的错误,是不被预期的运行方式 异常(Exception)与 Bug 的对比: 异常 运行时产生除0的情况 需要打...

对arcGis动态渲染标记点优化

import React from 'react'; import './index.less'; import { mapContext } from 'contexts/map'; import { Checkbox } from 'antd'; import esriConfig from 'gisConfig/esri.config'; impor...

linux环境下 C++性能测试工具 gprof + kprof + gprof2dot

1.gprof 很有名了,google下很多教程 g++ -pg -g  -o test test.cc ./test   //会生成gmon.out gprof ./test > prof.log 看一下对于我前面提到的huffman编码压缩+解码解压缩全部过程的一个程序 对于生成的prof.log ,wow, 很有用处的但是看起来有点累,不是吗:)...

python基础作业

1、 执行 Python 脚本的两种方式 ./python.py python python.py 2、 简述位、字节的关系 1字节 = 8位 3、 简述 ascii、unicode、utf-­‐8、gbk 的关系 ASCII 英文 Unicode =utf-16 utf-8 GBK 中文 4、 请写出 “李杰” 分别用 utf-­‐8 和 gbk 编码所...

Linux Shell系列教程之(三)Shell变量

本文是Linux Shell系列教程的第(三)篇,更多shell教程请看:Linux Shell系列教程 Shell作为一种高级的脚本类语言,也是支持自定义变量的。今天就为大家介绍下Shell中的变量相关知识。 为使Shell编程更有效,系统提供了一些Shell变量。Shell变量可以保存诸如路径名、文件名或者一个数字这样的变量名。 Shell将其中...