C++ 编译单元概述和全局变量的声明和定义
作者:网络转载 发布时间:[ 2015/11/5 11:38:31 ] 推荐标签:.NET 测试开发技术
在其他编译单元中使用全局变量时只要包含其所在头文件即可。
/**********类ConsumerThread使用全局变量************/
#include "consumerthread.h"
#include "res.h"
#include <QDebug>
ConsumerThread::ConsumerThread(QObject* parent)
: QThread(parent) {
}
ConsumerThread::ConsumerThread() {
}
ConsumerThread::~ConsumerThread() {
}
void ConsumerThread::run() {
for (int i = 0; i < g_nDataSize; i++) {
g_qsemUsedBytes.acquire();
qDebug()<<"Consumer "<<g_szBuffer[i % g_nBufferSize];
g_szBuffer[i % g_nBufferSize] = ' ';
g_qsemFreeBytes.release();
}
qDebug()<<"&&Consumer Over";
}
/**************************/
也可以把全局变量的声明和定义放在一起,这样可以防止忘记了定义,如上面的extern char g_szBuffer[g_nBufferSize]; 然后把引用它的文件中的#include "res.h"换成extern char g_szBuffer[];。
但是这样做很不好,因为你无法使用#include "res.h"(使用它,若达到两次及以上,出现重定义错误;注:即使在res.h中加#pragma once,或#ifndef也会出现重复定义,因为每个编译单元是单独的,都会对它各自进行定义),那么res.h声明的其他函数或变量,你也无法使用了,除非也都用extern修饰,这样太麻烦,所以还是推荐使用.h中声明,.cpp中定义的做法。
(5)静态全局变量(static)
注意使用static修饰变量,不能使用extern来修饰,即static和extern不可同时出现。
static修饰的全局变量的声明与定义同时进行,即当你在头文件中使用static声明了全局变量,同时它也被定义了。
static修饰的全局变量的作用域只能是本身的编译单元。在其他编译单元使用它时,只是简单的把其值复制给了其他编译单元,其他编译单元会另外开个内存保存它,在其他编译单元对它的修改并不影响本身在定义时的值。即在其他编译单元A使用它时,它所在的物理地址,和其他编译单元B使用它时,它所在的物理地址不一样,A和B对它所做的修改都不能传递给对方。
多个地方引用静态全局变量所在的头文件,不会出现重定义错误,因为在每个编译单元都对它开辟了额外的空间进行存储。
以下是Windows控制台应用程序代码示例:
/***********res.h**********/
static char g_szBuffer[6] = "12345";
void fun();
/************************/
/***********res.cpp**********/
#include "res.h"
#include <iostream>
using namespace std;
void fun() {
for (int i = 0; i < 6; i++) {
g_szBuffer[i] = 'A' + i;
}
cout<<g_szBuffer<<endl;
}
/************************/
/***********test1.h**********/
void fun1();
/************************/
/***********test1.cpp**********/
#include "test1.h"
#include "res.h"
#include <iostream>
using namespace std;
void fun1() {
fun();
for (int i = 0; i < 6; i++) {
g_szBuffer[i] = 'a' + i;
}
cout<<g_szBuffer<<endl;
}
/************************/
/***********test2.h**********/
void fun2();
/************************/
/***********test2.cpp**********/
#include "test2.h"
#include "res.h"
#include <iostream>
using namespace std;
void fun2() {
cout<<g_szBuffer<<endl;
}
/************************/
/***********main.cpp**********/
#include "test1.h"
#include "test2.h"
int main() {
fun1();
fun2();
system("PAUSE");
return 0;
}
/************************/
运行结果如下:
按我们的直观印象,认为fun1()和fun2()输出的结果都为abcdef,可实际上fun2()输出的确是初始值。然后我们再跟踪调试,发现res、test1、test2中g_szBuffer的地址都不一样,分别为0x0041a020、0x0041a084、0x0041a040,这解释了为什么不一样。
注:一般定义static 全局变量时,都把它放在.cpp文件中而不是.h文件中,这样不会给其他编译单元造成不必要的信息污染。
(6)全局常量(const)
const单独使用时,其特性与static一样(每个编译单元中地址都不一样,不过因为是常量,也不能修改,所以没有多大关系)。
const与extern一起使用时,其特性与extern一样。
extern const char g_szBuffer[]; //写入 .h中
const char g_szBuffer[] = "123456"; // 写入.cpp中
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11热门文章
常见的移动App Bug??崩溃的测试用例设计如何用Jmeter做压力测试QC使用说明APP压力测试入门教程移动app测试中的主要问题jenkins+testng+ant+webdriver持续集成测试使用JMeter进行HTTP负载测试Selenium 2.0 WebDriver 使用指南