头文件中定义全局变量
引言
之前在C++11中定义全局变量,要求在.h文件中的变量必须前面加extern关键字,在.cpp文件中定义。这样当多个源文件引入这个变量时,不会出现重复定义。
C++17及更高版本,可以使用关键字inline,在变量声明的同时定义,这样就不用分两个文件.h和.cpp了。
extern使用示例
将变量的声明和定义分离。
在头文件中使用extern声明变量:
// MyHeader.h
#pragma once
#include <QColor>
extern QColor g_borderColor; // 声明变量(不分配内存)
在源文件中进行定义,分配内存并初始化:
// MySource.cpp
#include "MyHeader.h"
QColor g_borderColor = QColor(Qt::blue); // 定义变量(分配内存)
原理说明:
extern 关键字:告诉编译器此变量在其他地方定义,当前文件仅声明(不分配内存)。
头文件保护:通过 #pragma once 或 #ifndef/#define 确保头文件仅被包含一次,避免重复声明。
注意:
初始化顺序:若变量依赖其他全局对象,需确保初始化顺序正确(可通过函数封装初始化逻辑)。
静态变量:若变量仅需在单个.cpp文件内使用,可用 static 关键字限制作用域,具体如下:
// MySource.cpp
static QColor g_borderColor = QColor(Qt::blue); // 仅在当前文件可见
关于关键字static的使用,可自行查找。
命名空间
在extern的基础上可以使用命名空间来替换extern,以实现相同的效果。
// Config.h
#pragma once
#include <QColor>
namespace Config {
extern QColor borderColor;
}
// Config.cpp
#include "Config.h"
QColor Config::borderColor = QColor(Qt::blue);
inline变量
在C++17及更高的版本,可以使用inline关键字在头文件中直接定义变量。
使用示例:
// MyHeader.h
#pragma once
#include <QColor>
namespace Config {
inline QColor borderColor = QColor(Qt::blue); // C++17+ 允许头文件直接定义
}
原理:inline 变量允许在多个翻译单元(.cpp文件)中存在同名定义,链接器会自动合并。
优点:无需单独的.cpp文件,代码更简洁。
限制:需要编译器支持 C++17(如 GCC 7+、Clang 5+、MSVC 19.15+)。
总结
优先使用 inline 变量(如果环境支持 C++17),代码最简洁。
兼容性要求高时,使用 extern + .cpp 的传统方式。
仅需单文件内使用时,可用 static 变量简化代码。
通过命名空间结合上述方法,既能组织代码,又能避免重复定义问题。