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

xcr*_*ypt 16 c c++ global-variables

好吧,我正在学习 C++,从来没有真正学过如何做不是OO的东西.我正试图获得更多C风格编码的经验.

GobalInformation.h

#pragma once

#ifndef GLOBALINFORMATION_H
#define GLOBALINFORMATION_H

#include "MapInformation.h"

namespace gi {
    MapInformation mapInf;
};

#endif
Run Code Online (Sandbox Code Playgroud)

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

我该如何解决这个问题?

par*_*mar 30

在头文件中只做

namespace gi {
    extern MapInformation mapInf;
};
Run Code Online (Sandbox Code Playgroud)

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

namespace gi {
    MapInformation mapInf;
};
Run Code Online (Sandbox Code Playgroud)

它会像你想象的那样工作.

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


Kev*_*pps 13

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

namespace gi {
    MapInformation& getMapInf()
    {
        static MapInformation result;
        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @xcrypt:全局对象初始化的顺序是未指定的(跨TU),因此如果您有一个需要另一个全局对象的全局对象,则无法确定它们是否会以正确的顺序初始化.拥有一个本地静态对象(基本上也是全局的,只有可见的限制)可以避免这种情况,因为你可以保证在`getMapInf()`返回时构造对象. (4认同)