简体   繁体   English

在C ++应用程序中使用全局变量

[英]Use of global variables in C++ application

I've used global variables without having any noticeable problems but would like to know if there are potential problems or drawbacks with my use of globals. 我使用了全局变量时没有出现任何明显的问题,但想知道我使用全局变量是否存在潜在的问题或弊端。

In the first scenario, I include const globals into a globals.h file, I then include the header into various implementation files where I need access to any one of the globals: 在第一种情况下,我将const全局变量包含在globals.h文件中,然后将标头包含在各种实现文件中,在这些文件中我需要访问任何一个全局变量:

globals.h
const int MAX_URL_LEN = 100;
const int MAX_EMAIL_LEN = 50;
…

In the second scenario, I declare and initialize the globals in an implementation file when the application executes. 在第二种情况下,我在应用程序执行时在实现文件中声明并初始化全局变量。 These globals are never modified again. 这些全局变量不会再被修改。 When I need access to these globals from a different implementation file, I use the extern keyword: 当我需要从其他实现文件访问这些全局变量时,可以使用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

Regarding the first scenario above, I've considered removing all of the different “include globals.h” and using extern where access to those globals is needed but have not done so since just including the globals.h is so convenient. 关于上面的第一种情况,我已经考虑过删除所有不同的“ include globals.h”,并在需要访问这些全局变量的地方使用extern,但由于包括了globals.h非常方便,因此没有这样做。

I am concerned that I will have different versions of the variables for each implementation file that includes globals.h. 我担心对于包含globals.h的每个实现文件,我将使用不同版本的变量。

Should I use extern instead of including the globals.h everywhere access is needed? 我应该使用extern而不是在需要访问的地方包括globals.h吗?

Please advise, and thank you. 请指教,谢谢。

Your implementation is fine for now. 您的实施目前还可以。 Globals become a problem when 当以下情况时,全局变量成为问题

  1. Your program grows and so does your number of globals. 您的程序在增长,您的全局数也在增加。
  2. New people join the team that don't know what you were thinking. 不认识您的想法的新人加入了团队。

Number 1 becomes particularly troublesome when your program becomes multi-threaded. 当您的程序成为多线程时,数字1特别麻烦。 Then you have a number of threads using the same data and you may require protection, which is difficult with just a list of globals. 然后,您有许多使用相同数据的线程,您可能需要保护,而仅使用全局变量列表就很难做到这一点。 By grouping data in separate files according to some criteria such as purpose or subject matter your code becomes more maintainable as it grows and you leave breadcrumbs for new programmers on the project to figure out how the software works. 通过根据诸如目的或主题之类的某些标准将数据分组到单独的文件中,您的代码将随着代码的增长而变得更加可维护,并且为项目中的新程序员留下了面包屑,以弄清软件的工作方式。

Global mutable variables 全局可变变量

  • provide invisible lines of influence across all of the code, and 在所有代码中提供看不见的影响力线,并且
  • you cannot rely on their values, or whether they've been initialized. 您不能依靠它们的值或它们是否已初始化。

That is, global mutable variables do for data flow what the global goto once did for execution flow, creating a spaghetti mess, wasting everyone's time. 也就是说,全局可变变量对数据流的作用与全局goto曾经对执行流的作用相同,造成了意大利面条混乱,浪费了每个人的时间。

Constant global variables are more OK, but even for those you run into 常量全局变量更合适,但即使对于那些遇到的变量

  • the initialization order fiasco. 初始化顺序惨败。

I remember how angry I got when I realized that all my troubles in wrapping a well known GUI framework, was due to it needlessly using global variables and provoking the initialization order fiasco. 我记得当我意识到包装一个众所周知的GUI框架时遇到的所有麻烦是由于它不必要地使用全局变量并引发了初始化顺序的惨败时,我感到非常生气。 First the anger was directed at the author, then at myself for being so stupid, not realizing what was going on (or rather, was not going on). 首先,愤怒是针对作者的,然后是针对我自己的愚蠢,他没有意识到正在发生的事情(或者说没有继续发生)。 Anyway. 无论如何。

A sensible solution to all this is Meyers' singletons, like 迈耶斯的单身人士是所有问题的明智解决方案,例如

inline
auto pi_decimal_digits()
    -> const string&
{
    static const string the_value = compute_pi_digits();
    return the_value;
}

For the case of a global that's dynamically initialized from some place that knows the value, “one programmer's constant is another programmer's variable”, there is no good solution, but one practical solution is to accept the possibility of a run time error and at least detect it: 对于从知道值的某个地方动态初始化的全局变量的情况,“一个程序员的常数就是另一个程序员的变量”,没有好的解决方案,但是一个实际的解决方案是接受运行时错误的可能性,至少检测到它:

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(); }

One issue with globals is that when you go to include 3rd party libraries in your code, sometimes they've used globals with the same names as yours. 全局变量的一个问题是,当您在代码中包含第三方库时,有时它们会使用与您的名字相同的全局变量。 There are definitely times when a global makes sense, but if possible you should also take care to do something like put it into a namespace. 在某些情况下,确实有一个全局意义是合理的,但如果可能的话,还应注意将其放入命名空间中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM