全局变量在C++应用中的应用

全局变量在C++应用中的应用,c++,extern,globals,C++,Extern,Globals,我使用全局变量时没有任何明显的问题,但我想知道使用全局变量是否存在潜在的问题或缺点 在第一个场景中,我将const globals包含到globals.h文件中,然后将头包含到各种实现文件中,在这些文件中我需要访问任何一个globals: globals.h const int MAX_URL_LEN = 100; const int MAX_EMAIL_LEN = 50; … 在第二个场景中,当应用程序执行时,我在实现文件中声明并初始化globals。这些全局变量不再被修改。当我需要从不同的

我使用全局变量时没有任何明显的问题,但我想知道使用全局变量是否存在潜在的问题或缺点

在第一个场景中,我将const globals包含到globals.h文件中,然后将头包含到各种实现文件中,在这些文件中我需要访问任何一个globals:

globals.h
const int MAX_URL_LEN = 100;
const int MAX_EMAIL_LEN = 50;
…
在第二个场景中,当应用程序执行时,我在实现文件中声明并初始化globals。这些全局变量不再被修改。当我需要从不同的实现文件访问这些全局文件时,我使用extern关键字:

main.cpp
char application_path[128];
char data_path[128];
// assign data to globals
strcpy(application_path,  get_dll_path().c_str());
…

do_something.cpp
extern char application _path[]; // global is now accessible in do_something.cpp
关于上面的第一个场景,我考虑过删除所有不同的“include globals.h”,并在需要访问这些globals的地方使用extern,但没有这样做,因为只包含globals.h非常方便

我担心对于包含globals.h的每个实现文件,我将有不同版本的变量

我是否应该使用extern而不是包含globals.h where,因为需要访问


请提供建议,谢谢。

您的实施目前还可以。当

你的程序在增长,你的全局用户数量也在增长。 新加入的人不知道你在想什么。 当您的程序变成多线程时,第一个问题变得特别麻烦。然后,您有许多线程使用相同的数据,您可能需要保护,而仅使用全局列表是很困难的。
通过根据一些标准(如目的或主题)将数据分组到不同的文件中,您的代码随着其增长而变得更易于维护,您可以为项目中的新程序员留下面包屑,以了解软件如何工作。

globals的一个问题是,当您在代码中包含第三方库时,有时他们会使用和你同名的globals。当然,有时全局变量是有意义的,但如果可能的话,您还应该注意将其放入命名空间中。

全局可变变量

在所有代码中提供不可见的影响线,以及 不能依赖它们的值,也不能依赖它们是否已初始化。 也就是说,全局可变变量对数据流的作用与全局goto对执行流的作用一样,造成了一团混乱,浪费了每个人的时间

常量全局变量更合适,但即使对于您遇到的变量

初始化命令失败了。 我记得当我意识到我在包装一个众所周知的GUI框架时遇到的所有麻烦都是由于它不必要地使用了全局变量并引发了初始化顺序的失败时,我是多么生气。首先,愤怒是针对作者的,然后是针对我自己,因为我太愚蠢了,没有意识到发生了什么,或者更确切地说,没有发生什么。无论如何

解决这一切的一个明智的办法是梅耶斯的单身汉,比如

inline
auto pi_decimal_digits()
    -> const string&
{
    static const string the_value = compute_pi_digits();
    return the_value;
}
对于从知道值的某个位置动态初始化的全局变量,“一个程序员的常数是另一个程序员的变量”,没有好的解决方案,但一个实际的解决方案是接受运行时错误的可能性,并至少检测它:

namespace detail {
    inline
    auto mutable_pi_digits()
        -> string&
    {
        static string the_value;
        return the_value;
    }
}  // namespace detail

inline
void set_pi_digits( const string& value )
{
    string& digits = detail::mutable_pi_digits();
    assert( digits.length() == 0 );
    digits = value;
}

inline
auto pi_digits()
    -> const string&
{ return detail::mutable_pi_digits(); }

建议:常数可以,但不要使用全局变量。根据需要传递数据或对象。您可能希望从整体上了解全局变量:您可以将外部变量放在某个位置;在标题中,然后包括该标题,而不是手动写入外部。另外,您不应该使用以u在全局名称空间开头的名称,因为标准是这样规定的。我强烈建议您创建能够访问全局数据的函数,例如extern char const*get_application_path;而不是提供对数据的直接访问。你的实现目前还可以,绝对不行。将逻辑常数作为可变的全局变量公开是非常不明智的。阿尔夫:你的观点很好理解,但有时快速和肮脏对于你想要完成的事情来说是完美的,尤其是当你不知道更好的事情时。@LightnessRacesinOrbit:我从不回应评论。你说的全局goto是什么意思?什么是全球性的?@ Lexness CraceSein轨道:C和C++缺乏全局GOTO,除非你计算隆格。是的,我知道;这就是为什么我问你为什么在C++的答案中提到一个假设的全球GOTO。我提到历史。具体来说,一个叫Edsger Dijkstra的家伙曾经写过一篇文章,现在很有名,叫做GOTO,被认为是有害的。我认为它可以从ACM作为一个经典。本文使用while和if等控制流结构,为后来被称为结构化编程铺平了道路。但是Dijkstra所讨论的问题并不是由C或C++本地GOTO引起的,至少在普通的小函数中是这样。这些问题是由非常真实的不受限制的全局goto特性引起的。您应该阅读“goto被认为是有害的” 有害的,1987年出版。这让人大开眼界。