Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.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++程序中制作全程序数据,而当所有的源文件包含这个“全局变量存储库”文件时,都不会遇到讨厌的错误。 我有2种方法在C++中做,我问哪种方法更好。< /P>_C++_Scope_Global Variables_Global - Fatal编程技术网

实现全局范围数据的最佳方法 我想在C++程序中制作全程序数据,而当所有的源文件包含这个“全局变量存储库”文件时,都不会遇到讨厌的错误。 我有2种方法在C++中做,我问哪种方法更好。< /P>

实现全局范围数据的最佳方法 我想在C++程序中制作全程序数据,而当所有的源文件包含这个“全局变量存储库”文件时,都不会遇到讨厌的错误。 我有2种方法在C++中做,我问哪种方法更好。< /P>,c++,scope,global-variables,global,C++,Scope,Global Variables,Global,在C#中,最简单的方法就是使用公共静态成员 C#: 在C++中你也可以做同样的事情 C++全局数据方式1 然而,也有外部因素 C++全局数据方式2 < C++ >哪一个更好,或者可能是我没有想到的另一种方式? 解决方案必须不会导致LNK2005“对象已定义”错误。更好的方法是将对象放在名称空间中 // header namespace global // or any appropriate name { extern Object data1 ; extern Object dat

在C#中,最简单的方法就是使用公共静态成员

C#:

在C++中你也可以做同样的事情

C++全局数据方式1 然而,也有外部因素

C++全局数据方式2 < C++ >哪一个更好,或者可能是我没有想到的另一种方式?
解决方案必须不会导致LNK2005“对象已定义”错误。

更好的方法是将对象放在名称空间中

// header
namespace global // or any appropriate name
{
   extern Object data1 ;
   extern Object data2 ;
}

// cpp
namespace global // or any appropriate name
{
   Object data1 ;
   Object data2 ;
}

正如命令中所说:要做到这一点,不要忘记在声明(在头文件中)中使用
extern
限定符来指定每个对象只有一个实例(在cpp文件中)。

公共静态变量只是全局变量,全局变量是坏的。如果一个对象依赖于您想要使其成为全局的某些数据,那么为该依赖项创建一个setter,并具有某种“工厂”类,该类将把您的应用程序从小型、独立的部分组装在一起,通过setter提供全局依赖项。这样,在伪代码中:

class A:
    has dependency1 of type X;
    has dependency2 of type Y;

class Factory:
    has sharedX of type X;
    has sharedY of type Y;

    init:
        sharedX = createX;
        sharedY = createY;

    wireApplication:
        instanceOfA = createA;
        instanceOfA.setDependency1(sharedX);
        instanceOfA.setDependency2(sharedY);
        return instanceOfA;
这样,A的依赖项就不会通过访问静态变量进行硬编码。这有几个好处。首先,它们更可见,因为您不会秘密地从实现文件中的其他类中提取信息。第二,它们不是一成不变的,因为你实际上可以创建一个无需拉动X和Y的图形。第三,你可以精确控制X和Y的寿命


查看Miško Hevery关于Singleton的优秀博客文章系列–您可以从那里开始并遵循链接。

如果您必须拥有一些全局对象,那么最简单的方法就是在需要访问它们的任何位置包含的头文件中声明它们,并在单个文件中定义它们源文件

您的方式#1使用一个只包含
静态成员的类,这意味着它本质上是在做名称空间的工作,那么为什么不使用名称空间呢

方式#2将两个对象聚合在一个类中,但如果两个对象之间没有真正的相互依赖关系,则这并没有特别的好处

我建议将对象放在
名称空间中
以防止全局名称空间受到潜在公共标识符(如
data1
)的污染

// File: globaldata.h
#ifndef GLOBALDATA_H
#define GLOBALDATA_H

#include "Object.h" // Definition of Object might be here

namespace GlobalData
{
    extern Object data1;
    extern Obejct data2;
}

#endif GLOBALDATA_H

然后你可以在其他类似的地方访问它们

#include "globaldata.h"

// Does something with global data
void f()
{
    GlobalData::data1.doSomething();
}

你很困惑。您的问题(“
LNK2005
”)在于链接,而不是源语言级别的作用域。C(c)将这些事情(虽然我不认为这是一件坏事)比C++更重要(但是C++也在某种程度上做到了,比如<代码> ExtNe>代码>关键字)。这个问题的任何解决方案都不能完全由编译器和预处理器来解决。链接器和您构建程序的方式将发挥作用

您的两种解决方案实际上都是使用
extern
(外部链接)来解决问题,这在第一种情况下是隐含的。实际上,“程序范围”的数据相当模糊。你是说“全过程”吗?还是在程序的所有实例中共享?根据错误消息,我假设您正在处理windows。您的程序是否有/使用DLL?此“程序范围”数据是否需要或应该在不同的DLL之间共享

在头文件中(我称之为Data.h):

在需要了解的任何源文件中:

#include "Data.h"
对于Data.cpp,您可以编写

#include "Data.h"

Object Data::data1;
Object Data::data1;

接吻

数据容器.h

DataContainer.cpp

#包括
命名空间数据容器{
对象数据1;
对象数据2;
}//命名空间数据容器

@bobobo:但在某种程度上,你可以在类中定义数据的范围,即使它只是在做命名空间的工作。@bobobo:你会感到困惑,因为你不能在C中拥有真正的全局数据。在C++中,所有的东西都需要在一个类中,而在C++中,你可以拥有真正的全局。因此,您将拥有
名称空间数据容器{Object data1;Object data2;}
。数据仍然是全局性的,但它就像在一个类中一样被包含。这个答案完全没有把握。名称空间并不能解决每个文件都需要包含这个数据容器头的问题。@bobobo:我不明白你为什么反对头文件。您可以将
data1
data2
放在全局名称空间中,并使用
extern对象data1需要使用它们的位置;但是,您仍然可以使用名称空间
名称空间glbl{extern Object data1;}
,而无需单独的头文件。无论哪种方式,我仍然认为在一个地方定义全局变量的类型和名称(即公共头文件)会更好。然后在匹配的源文件中,将它们全部定义。本质上,通过用extern替换static,您已经将类变成了一个名称空间。这样您就可以将main()放在任何您想要的地方了?Downvoter:天真地对自己抱怨“您永远不应该有全局范围的数据!”
// File: globaldata.cc
#include globaldata.h

namespace GlobalData
{

    Object data1;
    Object data2;
}
#include "globaldata.h"

// Does something with global data
void f()
{
    GlobalData::data1.doSomething();
}
namespace Data
{
    extern Object data1;
    extern Object data2;
}
#include "Data.h"
#include "Data.h"

Object Data::data1;
Object Data::data1;
#include "Data.h"

namespace Data
{
    Object data1;
    Object data2;
}
#pragma once
namespace DataContainer {
    extern Object data1;
    extern Object data2;
} // namespace DataContainer
#include <DataContainer.h>
namespace DataContainer {
    Object data1;
    Object data2;
}// namespace DataContainer