Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何声明和定义全局变量,以便正确地从所有头文件/源文件访问它们 < >我正在学习C++,从来没有真正学会如何做那些不是OO的东西。 我正试图获得更多的C风格编码经验 戈巴林信息_C++_C_Global Variables - Fatal编程技术网

如何声明和定义全局变量,以便正确地从所有头文件/源文件访问它们 < >我正在学习C++,从来没有真正学会如何做那些不是OO的东西。 我正试图获得更多的C风格编码经验 戈巴林信息

如何声明和定义全局变量,以便正确地从所有头文件/源文件访问它们 < >我正在学习C++,从来没有真正学会如何做那些不是OO的东西。 我正试图获得更多的C风格编码经验 戈巴林信息,c++,c,global-variables,C++,C,Global Variables,我希望能够从项目中的每个标题和cpp访问gi::mapInf。现在我在每个头中都包含globalinformation.h,所以我得到了多个定义的链接器错误 如何解决此问题?仅在头文件中执行 namespace gi { extern MapInformation mapInf; }; 在CPP文件中提供实际定义 namespace gi { MapInformation mapInf; }; 它将按你的意愿工作 如果跨动态链接库边界使用地图信息,则可能必须针对包含定义cpp

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


如何解决此问题?

仅在头文件中执行

namespace gi {
    extern MapInformation mapInf;
};
在CPP文件中提供实际定义

namespace gi {
    MapInformation mapInf;
};
它将按你的意愿工作


如果跨动态链接库边界使用地图信息,则可能必须针对包含定义cpp文件的库进行链接。另外,在Windows上,您可能必须使用

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

class GlobalData
{
public:
    int ticks_;
};   


//Other file
class ThatNeedsGlobalData
{
public:
ThatNeedsGlobalData(std::shared_ptr<GlobalData> globalData);
};
类全局数据
{
公众:
int-ticks;
};   
//其他文件
需要全局数据的类
{
公众:
需要全局数据(std::shared\ptr globalData);
};
这会给你省去一些麻烦


祝你好运

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

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

以下是您在使用全局变量时需要注意的几件事

  • 确保gobalinfo.h包含的头文件中的所有头文件也包含在#ifndefs中。(我看不到mapinformation.h,因此我假设您已经完成了此操作)

  • 与CPP一样,C编译器也不能确保不同转换单元(不同的C/CPP文件)中变量的初始化顺序。 因此,将头文件声明为

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


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


    下面是一个简单的示例:

    请注意,定义必须正好位于一个翻译单元中。在globalinformation.cpp中,我应该执行“MapInformation mapInf;”?@xcrypt。。我已经更新了我的答案,以反映在CPP文件中该做什么这意味着什么:“如果您跨动态链接库边界使用MapInformation,您可能必须链接包含定义CPP文件的库。”您能解释更多吗?您可能认为现在需要此全局变量,但我保证你会后悔的。@BjörnPollex详细说明了请注意:为什么你要使用
    #pragma一次
    和标题保护(顺便说一句,没有唯一标识符=>危险)?@Andre-Hmm,我在维基百科上读过一次,这样做可能会很好:@xcrypt:使用标题保护时,你应该附加一个唯一的部分,以避免名称冲突。您可以添加如下GUID:
    #如果NDEF全局信息(u H)8FF7B23E1B4D11E18852C5D6484019B
    #定义全局信息(u H)8FF7B23E1B4D1E18852C5D6484019B
    。如果您不需要可移植性,我建议您在编译器支持的情况下只使用一次
    #pragma
    。您可以在回答中解释一下初始化顺序问题的原因吗?@xcrypt:全局对象的初始化顺序未指定(跨TUs),因此,如果有一个全局对象需要另一个全局对象,则无法确定它们是否按正确的顺序初始化。使用本地静态对象(本质上也是全局的,只是具有受限的可见性)可以避免这种情况,因为您可以保证在
    getMapInf()
    返回时构造该对象。我想该函数应该是内联的还是声明为外部的?好吧,无论如何,我不得不这么做,这是一个很好的建议,但我还有另一个问题:在你的例子中,我如何设置“全局”变量?如何编写set方法?@xMutzelx,您可以使用getMapInf()返回的引用来设置或获取全局的值。例如gi::MapInformation otherMapInf();getMapInf()=其他Mapinf();这也是一个可能的解决办法,因此我将投赞成票。但我希望它是全局的原因之一是防止每个类都引用该信息(节省内存)。最后可能没什么关系,但嘿,我觉得这很酷:pSo你想在每个需要访问全局数据的类中保存指针/智能指针的大小吗?好啊试试看,看你是否觉得值得。以后您可以尝试其他解决方案。我不确定[2]是什么意思,请详细说明?似乎很重要
    //GlobalInformation.h
    
    namespace gi {
        extern MapInformation mapInf;
    };