当前位置: 首页 > wzjs >正文

株洲建设公司网站网站建设策划方案t

株洲建设公司网站,网站建设策划方案t,生猪价格网,连云港网站建设价位目录 1. 共享全局变量 2. 共享常量(const)变量 3. 与C语言交互 4. 显式模板实例化声明 5. 动态库符号管理 注意事项 关键总结 在C中,extern关键字主要用于声明变量、函数或模板的外部链接性,表明其定义存在于其他编译单元中…

目录

1. 共享全局变量

2. 共享常量(const)变量

3. 与C语言交互

4. 显式模板实例化声明

5. 动态库符号管理

注意事项

关键总结


在C++中,extern关键字主要用于声明变量、函数或模板的外部链接性,表明其定义存在于其他编译单元中。以下是extern的主要使用场景及示例:

1. 共享全局变量

当需要在多个源文件之间共享全局变量时,使用extern避免重复定义:

问题场景
在多个源文件中直接定义同名全局变量:

// file1.cpp
int globalVar = 10;// file2.cpp
int globalVar = 20;  // 重复定义!

后果

  • 链接阶段会触发 "multiple definition" 错误,违反一次定义规则(ODR)。

解决方案
使用extern声明,单一定义:

// header.h
extern int globalVar;  // 声明// file1.cpp
int globalVar = 10;    // 定义(唯一)// file2.cpp
#include "header.h"
void useVar() { globalVar = 30; }  // 正确使用

示例
考虑如下情形:

.
├── file1.cpp
├── file1.h
├── file2.cpp
├── file2.h
├── global.h
└── main.cpp1 directory, 6 files

代码:

//global.h
#pragma once
int global_var = 10;/***********************************************/
//file1.h
#pragma once
#include "global.h"void func1();/***********************************************/
//file1.cpp
#include "file1.h"
#include<iostream>void func1()
{std::cout<<"func1:"<<global_var<<","<<&global_var<<std::endl;
}/***********************************************/
//file2.h
#pragma once
#include "global.h"void func2();/***********************************************/
//file2.cpp
#include "file2.h"
#include<iostream>void func2()
{std::cout<<"func2:"<<global_var<<","<<&global_var<<std::endl;
}/***********************************************/
//main.cpp
#include "file1.h"
#include "file2.h"int main(int argc,char* argv[])
{func1();func2();return 0;
}

编译报错:

g++   file1.cpp file2.cpp main.cpp  -o demo /usr/bin/ld: /tmp/ccoKZ0nw.o:(.data+0x0): multiple definition of `global_var'; /tmp/ccMc4Z3v.o:(.data+0x0): first defined here
/usr/bin/ld: /tmp/cc743UGw.o:(.data+0x0): multiple definition of `global_var'; /tmp/ccMc4Z3v.o:(.data+0x0): first defined here
collect2: error: ld returned 1 exit status

解决办法:

修改global.h:

#pragma once
extern int global_var;

增加global.cpp:

#include "global.h"int global_var = 10;

编译:

g++  global.cpp  file1.cpp file2.cpp main.cpp  -o demo 

运行:

func1:10,0x55b9f94d3010
func2:10,0x55b9f94d3010

 可见file1.cpp和file2.cpp中用的是同一个global_var。


2. 共享常量(const)变量

const全局变量默认具有内部链接性(仅在当前文件可见)。若需跨文件共享,需用extern

问题场景
头文件中直接定义const变量:

// constants.h
const double PI = 3.14159;  // 每个包含此头的源文件生成独立副本// file1.cpp
#include "constants.h"  // 生成 PI 副本1// file2.cpp
#include "constants.h"  // 生成 PI 副本2

后果

  • 浪费内存空间(多份相同常量)。

  • 若需统一修改值,需重新编译所有包含该头文件的目标文件。

解决方案
使用extern声明,单一定义:

// constants.h
extern const double PI;  // 声明// constants.cpp
const double PI = 3.14159;  // 唯一定义(extern使常量具有外部链接性)

示例
考虑如下情形:

.
├── constants.h
├── file1.cpp
├── file1.h
├── file2.cpp
├── file2.h
└── main.cpp1 directory, 6 files

代码:

//constants.h
#pragma once
const float PI = 3.14;/*********************************/
//file1.h
#pragma once
#include "constants.h"void func1();/*********************************/
//file1.cpp
#include "file1.h"
#include<iostream>void func1()
{std::cout<<"func1:"<<PI<<","<<&PI<<std::endl;
}/*********************************/
//file2.h
#pragma once
#include "constants.h"void func2();/*********************************/
//file2.cpp
#include "file2.h"
#include<iostream>void func2()
{std::cout<<"func2:"<<PI<<","<<&PI<<std::endl;
}/*********************************/
//main.cpp
#include "file1.h"
#include "file2.h"int main(int argc,char* argv[])
{func1();func2();return 0;
}

编译运行:

$ g++  main.cpp  file1.cpp  file2.cpp   -o demo
$ ./demo 
func1:3.14,0x55c615beb008
func2:3.14,0x55c615beb01c

可以发现,file1.cpp和file2.cpp中的PI不是同一个PI。

解决办法:

修改constants.h:

#pragma once
extern const float PI;

新增constants.cpp:

#include "constants.h"extern const float PI = 3.14;// 测试发现,此处不写extern效果一样

目录结构变为:

.
├── constants.cpp
├── constants.h
├── file1.cpp
├── file1.h
├── file2.cpp
├── file2.h
└── main.cpp1 directory, 7 files

编译运行:

$ g++  main.cpp constants.cpp  file1.cpp  file2.cpp   -o demo
$ ./demo
func1:3.14,0x5639097c8004
func2:3.14,0x5639097c8004

可以看到,file1.cpp和file2.cpp中用的PI是同一个PI。


3. 与C语言交互

避免C++的名称修饰(name mangling),确保C++代码能调用C编译的函数:

问题场景
C++直接调用C函数时,未禁用名称修饰(name mangling):

// c_utils.h
void c_function();  // C函数声明// main.cpp
#include "c_utils.h"
int main() {c_function();  // C++编译后可能生成 _Z11c_functionv 的符号
}

后果

  • C语言编译的库中函数名为c_function,但C++生成修饰名,导致 链接器无法找到符号

解决方案
使用extern "C"禁用修饰:

// c_utils.h
#ifdef __cplusplus
extern "C" {  // 按C规则编译
#endif
void c_function();
#ifdef __cplusplus
}
#endif

4. 显式模板实例化声明

减少编译时间和代码体积,通过extern template避免隐式实例化:

问题场景
多文件中频繁使用同一模板实例:

// utils.h
template<typename T>
class Vector { /*...*/ };// file1.cpp
Vector<int> v1;  // 隐式实例化Vector<int>// file2.cpp
Vector<int> v2;  // 再次隐式实例化Vector<int>

后果

  • 每个编译单元生成相同模板实例化代码,导致 编译时间增加 和 二进制文件膨胀

解决方案
使用extern template声明:

// utils.h
extern template class Vector<int>;  // 声明:不在此处实例化// template_instances.cpp
template class Vector<int>;  // 显式实例化(唯一)

5. 动态库符号管理

问题场景
Windows动态库未显式导出符号:

// dll_lib.h
void dll_function();  // 未声明导出// dll_lib.cpp
void dll_function() {}  // 编译为DLL时符号未导出

后果

  • 其他模块调用时出现 "unresolved external symbol" 错误

解决方案
结合extern和平台特性导出符号:

// dll_lib.h
#ifdef MYLIB_EXPORTS
#define API __declspec(dllexport)
#else
#define API __declspec(dllimport)
#endifextern "C" API void dll_function();  // 声明为导出接口

注意事项

  • 一次定义规则(ODR)extern声明的变量/函数必须在程序中唯一一处定义

  • 避免全局变量滥用:过度使用extern变量可能导致代码耦合度高,建议优先使用命名空间或单例模式。

  • 类型一致性extern声明必须与定义处的类型严格匹配。


关键总结

场景不使用的后果extern的作用
跨文件共享全局变量链接错误(ODR违规)分离声明与定义,避免重复定义
跨文件共享常量内存冗余,修改不一致强制外部链接,统一内存实例
C/C++混合编程链接符号找不到禁用c++名称修饰,保持符号一致性
模板优化编译冗余,二进制膨胀抑制隐式实例化,提升编译效率
动态库接口符号不可见,链接失败控制符号可见性,明确导出/导入

核心原则extern通过 声明与定义的分离 和 链接性控制,解决跨编译单元、跨语言的协作问题,是C++模块化开发的关键工具,但需严格遵循语言规范以避免链接错误。


文章转载自:

http://2V1bTId0.rcwzf.cn
http://AqyqNHSU.rcwzf.cn
http://gDR2YlYq.rcwzf.cn
http://GFDVKrlu.rcwzf.cn
http://eq4EiX9Y.rcwzf.cn
http://EHSHniYy.rcwzf.cn
http://JctOPrGt.rcwzf.cn
http://H6XNug45.rcwzf.cn
http://wnRoVK4X.rcwzf.cn
http://21uiiHPn.rcwzf.cn
http://urPa2Al6.rcwzf.cn
http://VTJqXWxo.rcwzf.cn
http://XCOxGTa2.rcwzf.cn
http://WCyv4fkX.rcwzf.cn
http://rRxcrnxC.rcwzf.cn
http://gfLK6hB2.rcwzf.cn
http://EP0nQp4t.rcwzf.cn
http://0qrX2iUK.rcwzf.cn
http://RNfjYHE0.rcwzf.cn
http://SOplemUg.rcwzf.cn
http://CJV1f8Qs.rcwzf.cn
http://HihfnIMp.rcwzf.cn
http://c9HgC56U.rcwzf.cn
http://MfOHgeS3.rcwzf.cn
http://pP8mC7zM.rcwzf.cn
http://E2fPeDA7.rcwzf.cn
http://7G9k5RsO.rcwzf.cn
http://z9bbDtYl.rcwzf.cn
http://OGtCiPDx.rcwzf.cn
http://cKh68iWO.rcwzf.cn
http://www.dtcms.com/wzjs/685703.html

相关文章:

  • 临沂网站制作案例网站建设朋友圈
  • 百度公司官方网站陕西省交通建设厅网站
  • 塔城市建设局网站杭州久邦电力建设有限公司网站
  • 宜春网站建设联系方式网站经营性备案难不难
  • 做淘宝内部优惠券网站要钱么菜鸟零基础如何自学编程
  • 做盗文网站大创意网站
  • 网站优化提升排名免费公司网址怎么注册
  • 美食网站 原型 html 下载mui做浏览器网站跳转
  • 禅城做网站宁波城乡建设局管方网站
  • 顺德 网站设计建设项目银行网站
  • 深圳建设网站商天眼查官网查询企业
  • 开发一个网站的流程福州网
  • 怎样在阿里巴巴做网站北京手机网站设计公司
  • 软件网站关键词优化做网站公司没签合同
  • 企业做商城网站需要什么资质网站建设ssc源码平台
  • 漯河网站建设漯河什么网页传奇好玩
  • 购买完域名后怎么做网站英文网站制作
  • 大连华南网站制作公司企业公众号以及网站建设
  • 网站的优化排名怎么做营销网站的优势是什么
  • 做新媒体应该关注什么网站重庆网站建设必选承越
  • 建设网站项目总结wordpress音频播放器
  • 富阳住房和城乡建设部网站免费做图片链接网站
  • 织梦可以做婚纱影楼网站吗公司做网站需要准备哪些资料
  • 网站效果图确认表学校建设网站的意义
  • 深圳做网站最好的公热门传奇网页游戏排行榜
  • 淄博建设网站宁波网站建设排名
  • 免费网站推广文章企业门户网站制作价格怎么算
  • 做一个信息网站多少钱深圳网站建设的费用
  • 网站会员充值做哪个分录wordpress 喜欢
  • 广州从化建设网站官网网页内嵌网站