在头文件中包含全局变量
Include global variables in header file - c++
目前我正在使用相当大的一段代码来分析数据。在这段代码中,除了分析本身,我还包括了一些将在分析中使用的函数,一些与对象和一些全局变量相关的函数。我的代码有以下结构
#include "header1.h"
#include "header2.h"
...
#define global_variable_1 1
#define global_variable_2 3
...
double function1(){
<code>
{
double function2(){
<code>
{
...
main(){
<code>
}
现在我想让我的代码更优雅,更复杂,可编程正确。我正在考虑制作一个头文件,其中将包括我正在使用的头文件和一些函数,第二个头文件与其余的函数和最后一个头文件,将包含我使用的全局参数。
因此我将写入像
这样的内容#include "headers.h"
#include "functions.h"
#include "variables.h"
main(){
<code>
}
我的问题是,它是否可编程适当这样做,如果有另一个,也许更好的方式来包括全局变量
如果你试图使用全局变量,并且你知道它们是一个常量值,如PI,我会避免使用局部全局变量和#define宏。这是一个偏好问题,但随着时间的推移,我了解到在头文件中将它们声明为static const type name;
并在cpp文件中相应地设置值是更好的实践和更优雅的做法。我也不喜欢有一堆悬空的值或基本方法,所以我通常会将相似类型的值和方法分组,并将它们包含在一个类中,声明它们是静态的。下面是一个例子:
Utility.h
#ifndef UTILITY_H
#define UTILITY_H
#include <iostream>
#include <string>
#include <stdio.h>
class Utility {
public:
static void pressAnyKeyToQuit();
static std::string& toUpper( std::string& str );
static std::string& toLower( std::string& str );
private:
Utility(); // Not Implemented - This class is not an object and can not be declared.
Utility( const Utility& c ); // Copy Constructor - Not Implemented
Utility& operator=( const Utility&c ); Assignment Operator - Not Implemented
}; // Utility
#endif // UTILITY_H
Utility.cpp
#include "Utility.h"
// -------------------------------------------------------------------------
// pressAnyKeyToQuit()
void Utility::pressAnyKeyToQuit() {
std::cout << "Press any key to quit" << std::endl;
_getch();
} // pressAnyKeyToQuit
// -------------------------------------------------------------------------
// toUpper()
std::string& Utility::toUper( std::string& str ) {
std::transform( str.begin(), str.end(), str.begin(), ::toupper );
return str;
} // toUpper
// -------------------------------------------------------------------------
// toLower()
std::string& Utility::toLower( std::string& str ) {
std::transform( str.begin(), str.end(), str.begin(), ::tolower );
return str;
} // toLower
使用这些函数的例子如下:
main.cpp
#include <iostream>
#include <string>
#include "Utility.h"
int main() {
std::string strHello( "Hello World!" );
std::cout << strHello << std::endl;
std::cout << Utility::toLower( strHello ) << std::endl;
std::cout << Utility::toUpper( strHello ) << std::endl;
Utility::pressAnyKeyToQuit();
return 0;
} // main
对于这种类型的包含,这样做是非法的:
int main() {
Utility util;
util.pressAnyKeyToQuit();
} // main
这将失败,因为Utility默认构造函数是私有的或不可访问的,但是可以通过作用域解析操作符调用声明为静态的任何类型的函数或变量。下面是一个将被视为全局变量的const变量的示例。
GeneralMath.h
#ifndef GENERAL_MATH_H
#define GENERAL_MATH_H
class Math {
public:
static const float PI;
static const float PI_HAVLES;
static const float PI_2;
static const float ZERO;
inline static bool isZero( float fValue );
template<typename T>
inline static void swap( T& value1, T& value2 );
private:
Math();
Math( const Math& c ); // Not Implemented
Math& operator( const Math& c ); // Not Implemented
}; // Math
#include "GeneralMath.inl"
void dummy(); // does nothing used to have a method in the *.cpp file
#endif // GENERAL_MATH_H
GeneralMath.inl
// -------------------------------------------------------------------------
// isZero()
inline bool Math::isZero( float fValue ) {
if ( (fValue > -ZERO) && (fValue < ZERO) ) {
return true;
}
return false;
} // isZero
// -------------------------------------------------------------------------
// swap()
template<class T>
inline void Math::swap( T& value1, T& value2 ) {
T temp;
temp = value1;
value1 = value2;
value2 = temp;
} // swap
GeneralMath.cpp
#include "GeneralMath.h"
const float Math::PI = 4.0f * atan(1.0f); // tan(pi/4) = 1
const float Math::PI_HALVES = 0.5f * Math::PI;
const float Math::PI_2 = 2.0f * Math::PI;
const float Math::ZERO = static_cast<float>( 1e-7 );
void dummy(){return;}
在一个例子中使用:
main.cpp
#include <iostream>
#include "Utility.h"
#include "GeneralMath.h"
int main() {
float value = 3.14957;
if ( Math::isZero( value - Math::PI ) ) {
std::cout << "true" << std::endl;
} else {
std::cout << "false" << std::endl;
}
Utility::pressAnyKeyToQuit();
return 0;
} // main
我更喜欢这种方法,这样当常见的独立方法和常量变量经常在多个文件中使用并且具有类似的分组时,您就不会到处声明一堆#define或global。
另一方面如果你要创建的特定类对象依赖于特定的常量值而这个常量值是唯一的那么你可以在*.h或*.cpp文件中使用全局变量但我还是会声明它为static const type name;
这样做的简单之处在于在需要的地方包含*.h文件,并在需要的地方使用类名和作用域解析操作符,后面跟着const变量或静态方法。
您也可以使用类似的方法,不使用类,也不通过将类包含在名称空间中而将其声明为静态,但这可能会导致问题,因为其他开发人员可能具有相同的名称空间,这可能会在解析名称时产生冲突。这就是为什么我更喜欢类方法并将它们声明为静态成员的原因。
记住这些类不是对象,它们不能被构造,所有的成员必须是静态的!
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 当vector是tje全局变量时,c++中vector的内存管理
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 内联函数中具有内部链接的全局变量
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 全局变量 多读取器 一个写入器多线程安全?
- 如果全局变量默认是外部变量,为什么要添加"extern"关键字?
- 不同作用域中的静态变量和全局变量
- C++ 在编译时具有函数计算全局变量
- 修改程序的入口点时未调用全局变量的构造函数
- 使用 std::ios_base::Init 正确初始化全局变量
- 为什么我的全局变量似乎没有变化?
- 如何创建用于多个源文件的全局变量/包含/函数
- 当在其中定义全局变量时,如何在.cpp中包含 C 样式的 .h
- C 使用c库,其中包含标题文件中定义的全局变量
- 单击按钮时,全局变量包含垃圾
- 在 C++ 中包含和访问线程全局变量
- 包含文件会导致全局变量出现多个定义错误
- 在头文件中包含全局变量
- 编译器是否在全局符号表中包含没有静态修饰符的全局变量