C++ 如何声明和定义全局变量以便从所有头文件/源文件正确访问它们

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8317010/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:21:41  来源:igfitidea点击:

how to declare and define global variables in order to access them from all headers/source files properly

c++cglobal-variables

提问by xcrypt

Well, I'm learningC++ and never really learned how to do stuff that is not OO. I'm trying to get a bit more experience coding in C style.

好吧,我正在学习C++,但从未真正学会如何做不是面向对象的东西。我正在尝试获得更多的 C 风格编码经验。

GobalInformation.h

全局信息.h

#pragma once

#ifndef GLOBALINFORMATION_H
#define GLOBALINFORMATION_H

#include "MapInformation.h"

namespace gi {
    MapInformation mapInf;
};

#endif

I would like to be able to access gi::mapInf from every header and cpp in my project. Right now I'm including globalinformation.h in every header, so I'm getting linker errors with multiple definitions.

我希望能够从我的项目中的每个标头和 cpp 访问 gi::mapInf。现在我在每个标头中都包含 globalinformation.h,所以我收到多个定义的链接器错误。

How can I work around the problem?

我该如何解决这个问题?

回答by parapura rajkumar

In header file only do

在头文件中只做

namespace gi {
    extern MapInformation mapInf;
};

In CPP file provide the actual definition.

在 CPP 文件中提供实际定义。

namespace gi {
    MapInformation mapInf;
};

It will work as you intend.

它会按您的意愿工作。

If you are using the MapInformationacross dynamic link library boundaries you might have to link against the library that includes the definition cpp file. Also on Window you might have to use dllimport/dllexport

如果您跨动态链接库边界使用MapInformation,则可能必须链接到包含定义 cpp 文件的库。同样在 Window 上,您可能必须使用dllimport/dllexport

回答by Kevin Hopps

Be aware that having globals in multiple compilation units can easily lead to order-of-initialization problems. You may wish to consider replacing each global with a function that returns a reference. In your case, put this in one cpp file and declare it in the header:

请注意,在多个编译单元中使用全局变量很容易导致初始化顺序问题。您可能希望考虑用返回引用的函数替换每个全局变量。在你的情况下,把它放在一个 cpp 文件中并在标题中声明它:

namespace gi {
    MapInformation& getMapInf()
    {
        static MapInformation result;
        return result;
    }
}

回答by SChepurin

Global variables are C, but namespaces are C++. There is a good discussion on using global variables and how they can be replaced by Singleton pattern: Globals and Singletons

全局变量是 C,但命名空间是 C++。关于使用全局变量以及如何用单例模式替换它们有很好的讨论:Globals and Singletons

And here is a simple sample: CPP/Classes/Singleton

这是一个简单的示例:CPP/Classes/Singleton

回答by mantler

Perhaps a better solution is to create a global object that contains all your global data. Then pass a smart pointer to the classes that actually need to access this shared global data. Example:

也许更好的解决方案是创建一个包含所有全局数据的全局对象。然后将智能指针传递给实际需要访问此共享全局数据的类。例子:

class GlobalData
{
public:
    int ticks_;
};   


//Other file
class ThatNeedsGlobalData
{
public:
ThatNeedsGlobalData(std::shared_ptr<GlobalData> globalData);
};

This will save you some trouble.

这将为您省去一些麻烦。

Good luck!

祝你好运!

回答by Guru Govindan

Here are a few things that you need to take care of while trying to use global variables the way you have used.

以下是在尝试以您使用的方式使用全局变量时需要注意的一些事项。

  1. Ensure that all the header files that the header files that GobalInformation.h includes are also enclosed insides #ifndefs. (I could not see mapinformation.h so I assume you have done it)

  2. Just like CPP, C compiler also does not ensure order of the initialization of variables in different translation units(different C/CPP files). Hence declare the header file as

    //GlobalInformation.h
    
    namespace gi {
        extern MapInformation mapInf;
    };
    
  3. In a function that you know would be called first initialize the variable. This way lazy-initialization can also be acheived in C.

  1. 确保 GobalInformation.h 包含的头文件中的所有头文件也包含在 #ifndefs 中。(我看不到 mapinformation.h 所以我假设你已经完成了)

  2. 就像 CPP 一样,C 编译器也不保证不同翻译单元(不同 C/CPP 文件)中变量的初始化顺序。因此将头文件声明为

    //GlobalInformation.h
    
    namespace gi {
        extern MapInformation mapInf;
    };
    
  3. 在您知道将被调用的函数中,首先初始化变量。这种惰性初始化也可以在 C 中实现。