当前位置: 首页 > 编程日记 > 正文

C++中extern的使用

在C++中,extern主要有两个作用:(1)、extern声明一个变量或函数;(2)、extern与”C”一起连用,用于链接指定。关于extern “C”的使用可以参考: http://blog.csdn.net/fengbingchun/article/details/78634831 ,这里主要介绍extern声明一个变量或函数时的用法。

extern可置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示编译器遇到此变量或函数时,在其它模块中寻找其定义。

如果想声明一个变量而非定义它,就在变量名称前加关键字extern,而且不要显示地初始化变量。任何包含了显示初始化的声明即成为定义。我们能给由extern关键字标记的变量赋一个初始值,但是这么做也就抵消了extern的作用。extern语句如果包含初始值就不再是声明,而变成定义了。在函数体内部,如果试图初始化一个由extern关键字标记的变量,将引发错误变量能且只能被定义一次,但是可以被多次声明。声明和定义的区别看起来也许微不足道,但实际上却非常重要。如果要在多个文件中使用同一个变量,就必须将声明和定义分离。此时,变量的定义必须出现在且只能出现在一个文件中,而其它用到该变量的文件必须对其进行声明,却绝对不能重复定义。

某些时候有这样一种const变量,它的初始值不是一个常量表达式,但又确实有必要在文件间共享。这种情况下,我们不希望编译器为每个文件分别生成独立的变量。相反,我们想让这类const对象像其它(非常量)对象一样工作,也就是说,只在一个文件中定义const,而在其它多个文件中声明并使用它。解决的办法是,对于const变量不管是声明还是定义都添加extern关键字,这样只需定义一次就可以了。如果想在多个文件之间共享const对象,必须在变量的定义之前添加extern关键字

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

extern template declaration; // 实例化声明
template declaration; // 实例化定义
declaration是一个类或函数声明,其中所有模板参数已被替换为模板实参。 当编译器遇到extern模板声明时,它不会在本文件中生成实例化代码。将一个实例化声明为extern就表示承诺在程序其它位置有该实例化的一个非extern声明(定义)。对于一个给定的实例化版本,可能有多个extern声明,但必须只有一个定义。由于编译器在使用一个模板时自动对其实例化,因此extern声明必须出现在任何使用此实例化版本的代码之前。当编译器遇到一个实例化定义(与声明相对)时,它为其生成代码。 对每个实例化声明,在程序中某个位置必须有其显示的实例化定义。一个类模板的实例化定义会实例化该模板的所有成员,包括内联的成员函数。当编译器遇到一个实例化定义时,它不了解程序使用哪些成员函数。因此,与处理类模板的普通实例化不同,编译器会实例化该类的所有成员。即使我们不使用某个成员,它也会被实例化。因此,我们用来显示实例化一个类模板的类型,必须能用于模板的所有成员。 在一个类模板的实例化定义中,所用类型必须能用于模板的所有成员函数

模板显示实例化(explicit instantiation):一个声明,为所有模板参数提供了显示实参。用来指导实例化过程。如果声明是extern的,模板将不会被实例化;否则,模板将利用指定的实参进行实例化。对每个extern模板声明,在程序中某处必须有一个非extern的显示实例化

关键字extern为声明但不定义一个对象提供了一种方法,实际上它类似于函数声明,承诺了该对象会在其它地方被定义或者在此文本文件中的其它地方,或者在程序的其它文本文件中。extern声明不会引起内存被分配,它可以在同一文件中或同一程序的不同文件中出现多次。关键字extern也可以在函数声明中指定,唯一的影响是将该声明为隐式属性,在其它地方定义,变为显示的。extern关键字告诉编译器,”这个变量可能定义在这个模块或其它模块中”,一个extern声明并没有生成数据,它仅表明这个数据是共享的。这个变量必须是在别处定义过的,而且它只能定义一次。

以下是测试代码:

extern.hpp:

#ifndef FBC_CPPBASE_TEST_EXTERN_HPP_
#define FBC_CPPBASE_TEST_EXTERN_HPP_namespace extern_ {extern const int bufsize; // 与.cpp中定义的bufsize是同一个int test_extern_1();
int test_extern_2();} // namespace extern_#endif // FBC_CPPBASE_TEST_EXTERN_HPP_
extern.cpp:

#include "extern.hpp"
#include <iostream>extern std::string extern_variable_blog_addr;
extern std::string extern_variable_github_addr;
extern int extern_function_add(int a, int b);
extern const std::string extern_function_name();namespace extern_ {namespace {int fcn() { return 0; }
}extern double pi = 3.1415; // 定义/* reference: C++ Primer(Fifth 中文版) pages 63
某些时候有这样一种const变量,它的初始值不是一个常量表达式,但又确实有必要在文件间共享。
这种情况下,我们不希望编译器为每个文件分别生成独立的变量。相反,我们想让这类const对象
像其它(非常量)对象一样工作,也就是说,只在一个文件中定义const,而在其它多个文件中声明
并使用它。解决的办法是,对于const变量不管是声明还是定义都添加extern关键字,这样只需定义一次就可以了
*/
extern const int bufsize = fcn();int test_extern_1()
{extern int i; // 声明i而非定义iint j; // 声明并定义j//extern double pi = 3.1415; // 定义,在函数体内部,如果试图初始化一个由extern关键字标记的变量,将引发错误return 0;
}int test_extern_2()
{fprintf(stdout, "blob addr: %s\n", extern_variable_blog_addr.c_str());fprintf(stdout, "github addr: %s\n", extern_variable_github_addr.c_str());fprintf(stdout, "a + b = %d\n", extern_function_add(2, 3));fprintf(stdout, "name: %s\n", extern_function_name().c_str());return 0;
}} // namespace extern_
extern2.hpp:

#ifndef FBC_CPPBASE_TEST_EXTERN2_HPP_
#define FBC_CPPBASE_TEST_EXTERN2_HPP_#include <string>extern std::string extern_variable_blog_addr;
extern std::string extern_variable_github_addr;
extern int extern_function_add(int a, int b);
extern const std::string extern_function_name();#endif // FBC_CPPBASE_TEST_EXTERN2_HPP_
extern2.cpp:

#include "extern2.hpp"std::string extern_variable_blog_addr{ "http://blog.csdn.net/fengbingchun" };
std::string extern_variable_github_addr{ "https://github.com/fengbingchun" };int extern_function_add(int a, int b)
{return (a + b);
}extern const std::string extern_function_name()
{return "C++";
}

GitHub: https://github.com/fengbingchun/Messy_Test

相关文章:

Python识别文字,实现看图说话 | CSDN博文精选

作者 | 张小腿来源 | CSDN博客现在写文件很多网站都不让复制了&#xff0c;所以每次都是截图然后发到QQ上然后用手机QQ的文字识别再发回电脑。感觉有点小麻烦了&#xff0c;所以想自己写一个小软件方便方便自己&#xff0c;就有了这篇了&#xff1a;首先语言是Python&#xff0…

Oracle Hints具体解释

在向大家具体介绍Oracle Hints之前&#xff0c;首先让大家了解下Oracle Hints是什么&#xff0c;然后全面介绍Oracle Hints&#xff0c;希望对大家实用。基于代价的优化器是非常聪明的&#xff0c;在绝大多数情况下它会选择正确的优化器&#xff0c;减轻了DBA的负担。但有时它也…

主成分分析(PCA)简介

主成分分析(Principal Components Analysis, PCA)是一个简单的机器学习算法&#xff0c;可以通过基础的线性代数知识推导。假设在Rn空间中我们有m个点{x(1),…,x(m)}&#xff0c;我们希望对这些点进行有损压缩。有损压缩表示我们使用更少的内存&#xff0c;但损失一些精度去存储…

01-HTML基础与进阶-day6-录像281

04css选择器.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Document</title><style type"text/css">/* p div 标签选择器*/p {color: red; /* k:v color表示样式属性 颜…

百度CTO王海峰:深度学习如何大规模产业化?

编者按&#xff1a;10月17日-19日&#xff0c;2019年中国计算机大会&#xff08;CNCC2019&#xff09;在苏州举办。百度首席技术官王海峰在会上发表题为《深度学习平台支撑产业智能化》的演讲&#xff0c;分享了百度关于深度学习技术推动人工智能发展及产业化应用的思考。以下为…

Kali Linux***测试

Kali Linux***测试实战 第一章http://drops.wooyun.org/tips/826 1.1 Kali Linux简介如果您之前使用过或者了解BackTrack系列Linux的话&#xff0c;那么我只需要简单的说&#xff0c;Kali是BackTrack的升级换代产品&#xff0c;从Kali开始&#xff0c;BackTrack将成为历史。如果…

一站式解决:隐马尔可夫模型(HMM)全过程推导及实现

作者 | 永远在你身后转载自知乎用户永远在你身后【导读】隐马尔可夫模型&#xff08;Hidden Markov Model&#xff0c;HMM&#xff09;是关于时许的概率模型&#xff0c;是一个生成模型&#xff0c;描述由一个隐藏的马尔科夫链随机生成不可观测的状态序列&#xff0c;每个状态生…

CUDA Samples: Image Process: BGR to BGR565

图像像素格式BGR565是每一个像素占2个字节&#xff0c;其中Blue占5位&#xff0c;Green占6位&#xff0c;Red占5位。在OpenCV中&#xff0c;BGR到BGR565的每一个像素的计算公式是&#xff1a;unsigned short dst (unsigned short)((B >> 3) | ((G & ~3) << 3)…

NoSQL数据库探讨 - 为什么要用非关系数据库?

源地址&#xff1a;http://robbin.javaeye.com/blog/524977 随着互联网web2.0网站的兴起&#xff0c;非关系型的数据库现在成了一个极其热门的新领域&#xff0c;非关系数据库产品的发展非常迅速。而传统的关系数据库在应付web2.0网站&#xff0c;特别是超大规模和高并发的SNS类…

手机内存RAM、ROM简介

手机内存包含两个&#xff1a;一个是运行内存(RAM)&#xff0c;一个是机身内存(ROM)。两者的功能有所不同&#xff0c;运行内存是对手机操作系统和其它程序运行过程中&#xff0c;产生的临时数据进行存储的媒介。如果手机运行的程序比较多&#xff0c;占用运行内存空间较大&…

一个月入门Python爬虫,轻松爬取大规模数据

如果你仔细观察&#xff0c;就不难发现&#xff0c;懂爬虫、学习爬虫的人越来越多&#xff0c;一方面&#xff0c;互联网可以获取的数据越来越多&#xff0c;另一方面&#xff0c;像 Python这样一个月入门Python爬虫&#xff0c;轻松爬的编程语言提供越来越多的优秀工具&#x…

软件包管理 之 软件在线升级更新yum 图形工具介绍

作者&#xff1a;北南南北来自&#xff1a;LinuxSir.Org提要&#xff1a;yum 是Fedora/Redhat 软件包管理工具&#xff0c;包括文本命令行模式和图形模式&#xff1b;图形模式的yum也是基于文本模式的&#xff1b;目前yum图形前端程序主要有 yumex和kyum &#xff1b; 正文一、…

[PHPUnit]自动生成PHPUnit测试骨架脚本-提供您的开发效率【2015升级版】

2019独角兽企业重金招聘Python工程师标准>>> 场景 在编写PHPUnit单元测试代码时&#xff0c;其实很多都是对各个类的各个外部调用的函数进行测试验证&#xff0c;检测代码覆盖率&#xff0c;验证预期效果。为避免增加开发量&#xff0c;可以使用PHPUnit提供的phpuni…

ORL Faces Database介绍

ORL人脸数据集共包含40个不同人的400张图像&#xff0c;是在1992年4月至1994年4月期间由英国剑桥的Olivetti研究实验室创建。此数据集下包含40个目录&#xff0c;每个目录下有10张图像&#xff0c;每个目录表示一个不同的人。所有的图像是以PGM格式存储&#xff0c;灰度图&…

张俊林:BERT和Transformer到底学到了什么 | AI ProCon 2019

演讲嘉宾 | 张俊林&#xff08;新浪微博机器学习团队AI Lab负责人&#xff09;编辑 | Jane出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;【导读】BERT提出的这一年&#xff0c;也是NLP领域迅速发展的一年。学界不断提出新的预训练模型&#xff0c;刷新各…

Eclipse创建web工程时,报错Dynamic Web Module 3.0 requires Java 1.6 or newer.

报错&#xff1a; 解决方案&#xff1a; 1.打开eclipse工具栏window->preferences 2.打开java->compiler 3.选择compiler compliance level在1.6以上版本&#xff08;此处选择1.8&#xff09; 4.点击apply and close保存修改&#xff0c;即可 转载于:https://www.cnblogs…

Maven学习总结(八)——使用Maven构建多模块项目

2019独角兽企业重金招聘Python工程师标准>>> Maven学习总结(八)——使用Maven构建多模块项目 在平时的Javaweb项目开发中为了便于后期的维护&#xff0c;我们一般会进行分层开发&#xff0c;最常见的就是分为domain&#xff08;域模型层&#xff09;、dao&#xff0…

哈工大、清华、CSDN、嵌入式视觉联盟合办的 AIoT 盛会,你怎么舍得错过?!

2019 嵌入式智能国际大会即将来袭&#xff01;随着物联网和人工智能技术的飞速发展与相互渗透&#xff0c;万物智联的新赛道已经开始显现。据中商产业研究院《2016—2021年中国物联网产业市场研究报告》显示&#xff0c;预计到2020年&#xff0c;中国物联网的整体规模将达2.2万…

OpenCV3.3中主成分分析(Principal Components Analysis, PCA)接口简介及使用

OpenCV3.3中给出了主成分分析(Principal Components Analysis, PCA)的实现&#xff0c;即cv::PCA类&#xff0c;类的声明在include/opencv2/core.hpp文件中&#xff0c;实现在modules/core/src/pca.cpp文件中,其中&#xff1a;(1)、cv::PCA::PCA&#xff1a;构造函数&#xff1…

Spring MVC配置

为什么80%的码农都做不了架构师&#xff1f;>>> 一、传统方式配置Spring MVC &#xff08;1&#xff09;导入jar包 需要导入如下的jar包 junit-3.8.1.jar spring-core-3.0.5.RELEASE.jar commons-logging-1.1.1.jar spring-context-3.0.5.REL…

主成分分析(PCA)Python代码实现

主成分分析(Principal Components Analysis, PCA)简介可以参考&#xff1a; http://blog.csdn.net/fengbingchun/article/details/78977202 这里是参照 http://sebastianraschka.com/Articles/2014_pca_step_by_step.html 文章中的code整理的Python代码&#xff0c;实现过程为…

AI发展这一年:不断衍生的技术丑闻与抵制声潮

作者 | AI Now学院译者 | Raku编辑 | Jane出品 | AI科技大本营&#xff08;ID: rgznai100&#xff09;【导读】10月2日&#xff0c;纽约大学AI Now学院在纽约大学斯克博剧院&#xff08;Skirball Theatre&#xff09;组织召开了第四届年度AI Now研讨会。研讨会邀请了业内组织者…

Distributed Configuration Management Platform(分布式配置管理平台)

2019独角兽企业重金招聘Python工程师标准>>> 专注于各种 分布式系统配置管理 的通用组件/通用平台, 提供统一的配置管理服务。 主要目标&#xff1a; 部署极其简单&#xff1a;同一个上线包&#xff0c;无须改动配置&#xff0c;即可在 多个环境中(RD/QA/PRODUCTION…

如何利用zendstudio新建 或导入php项目

为什么80%的码农都做不了架构师&#xff1f;>>> 一、利用ZendStudio创建 PHP Project 1. 打开ZendStudio, 选择&#xff1a;File &agrave; New &agrave; PHP Project, 如下图所示: 于是弹出如下界面&#xff1a; 在”Project name”后输入工程名(比如我这里…

一文读懂GoogLeNet神经网络 | CSDN博文精选

作者 | .NY&XX来源 | CSDN博客本文介绍的是著名的网络结构GoogLeNet&#xff0c;目的是试图领会其中结构设计思想。GoogLeNet特点优化网络质量的生物学原理GoogLeNet网络结构的动机GoogLeNet架构细节Inception模块和普通卷积结构的差异辅助分类器GoogLeNet网络架构GoogLeNe…

C++中的函数签名

C中的函数签名(function signature)&#xff1a;包含了一个函数的信息&#xff0c;包括函数名、参数类型、参数个数、顺序以及它所在的类和命名空间。普通函数签名并不包含函数返回值部分&#xff0c;如果两个函数仅仅只有函数返回值不同&#xff0c;那么系统是无法区分这两个函…

MyEclipse断点调试

2019独角兽企业重金招聘Python工程师标准>>> 1、在编辑的程序的左边&#xff0c;你会看到一条浅浅的灰色编带&#xff0c;在这里设置断点。 2、设置断点的方法有很多 方法&#xff1a;1&#xff09;、双击 &#xff1b; 2&#xff09;、右键&#xff0c;选择“Toggl…

C primer plus 练习题 第三章

5. 1 #include <stdio.h>2 3 int main()4 {5 float you_sec;6 printf("请输入你的年龄:");7 scanf("%f", &you_sec);8 printf("年龄合计:%e 秒!\n", you_sec * 3.156e7);9 getchar(); 10 return 0; 11 }

Echache整合Spring缓存实例讲解

2019独角兽企业重金招聘Python工程师标准>>> 摘要&#xff1a;本文主要介绍了EhCache&#xff0c;并通过整合Spring给出了一个使用实例。 一、EhCache 介绍 EhCache 是一个纯Java的进程内缓存框架&#xff0c;具有快速、精干等特点&#xff0c;是Hibernate中默认的C…

灰度图像直方图均衡化公式及实现

图像的直方图&#xff1a;直方图是图像中像素强度分布的图形表达方式。它统计了每一个强度值所具有的像素个数。直方图均衡化&#xff1a;是通过拉伸像素强度分布范围来增强图像对比度的一种方法。是图像处理领域中利用图像直方图对对比度进行调整的方法。均衡化指的是把一个分…