Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.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+;+;) 让我们考虑C++类。在执行开始时,我希望从XML文件中读取一组值,并将它们分配给该类的7个数据成员。这些值在整个执行过程中不会更改,它们必须由相关类的所有对象/实例共享。静态数据成员是实现这种行为的最优雅的方式吗?(当然,我不考虑全局变量)听起来像是静态变量对我的一个很好的使用。您更多地将这些作为固定参数而不是变量使用,这些值需要合法地共享。_C++_Variables_Static_Static Members - Fatal编程技术网

我应该使用静态数据成员吗?(C+;+;) 让我们考虑C++类。在执行开始时,我希望从XML文件中读取一组值,并将它们分配给该类的7个数据成员。这些值在整个执行过程中不会更改,它们必须由相关类的所有对象/实例共享。静态数据成员是实现这种行为的最优雅的方式吗?(当然,我不考虑全局变量)听起来像是静态变量对我的一个很好的使用。您更多地将这些作为固定参数而不是变量使用,这些值需要合法地共享。

我应该使用静态数据成员吗?(C+;+;) 让我们考虑C++类。在执行开始时,我希望从XML文件中读取一组值,并将它们分配给该类的7个数据成员。这些值在整个执行过程中不会更改,它们必须由相关类的所有对象/实例共享。静态数据成员是实现这种行为的最优雅的方式吗?(当然,我不考虑全局变量)听起来像是静态变量对我的一个很好的使用。您更多地将这些作为固定参数而不是变量使用,这些值需要合法地共享。,c++,variables,static,static-members,C++,Variables,Static,Static Members,静态成员在这里工作,并且完全可以接受。另一种选择是对包含这些成员的类使用一个,以确保它们只构造/设置一次。正如其他人所提到的,在这种情况下使用静态成员似乎是合适的。只要记住,这不是万无一失的;全局数据的一些问题适用于静态成员: 您无法控制静态成员的初始化顺序,因此需要确保没有全局或其他静态引用这些对象。有关更多详细信息,以及避免此问题的一些提示,请参阅 如果您在多线程环境中访问这些,则需要确保在生成任何线程之前,成员已完全初始化 听起来像是对静态类成员的适当使用。只是别忘了它们是真正的全局变量

静态成员在这里工作,并且完全可以接受。另一种选择是对包含这些成员的类使用一个,以确保它们只构造/设置一次。

正如其他人所提到的,在这种情况下使用静态成员似乎是合适的。只要记住,这不是万无一失的;全局数据的一些问题适用于静态成员:

  • 您无法控制静态成员的初始化顺序,因此需要确保没有全局或其他静态引用这些对象。有关更多详细信息,以及避免此问题的一些提示,请参阅
  • 如果您在多线程环境中访问这些,则需要确保在生成任何线程之前,成员已完全初始化

    • 听起来像是对静态类成员的适当使用。只是别忘了它们是真正的全局变量,具有名称空间和(可能)一些保护。因此,如果您的应用程序有可能在某一天演化出单独的“环境”,或者需要为每个“环境”都提供一组全局变量,那么您就会陷入困境


      如Rob建议的,考虑使用单体,后者更容易转变为某种被管理的环境变量。

      < P>这不是一个干净的设计。静态类成员是全局状态和

      如果这是一个中小型项目,并且您对自动测试没有很高的目标,那么它可能不会给您带来麻烦,但是既然您问了:有更好的方法

      更简洁的设计是为类创建一个工厂,让工厂在构建类时将您的七个变量传递给类。然后,工厂负责确保所有实例共享相同的值

      这样,您的类就成为可测试的,并且您已经正确地分离了您的关注点


      PS..

      只要您考虑到可测试性,并且除了在文件中读取之外,您还有另一种设置静态变量的方法,并且您不依赖于在整个流程执行期间保持不变的数据,那么您应该可以


      我发现,在设计代码时考虑编写测试有助于保持代码的良好分解性和可重用性。

      是的,静态数据成员是您需要的。但是您必须注意静态变量的初始化/销毁顺序。在C++中,没有任何机制可以确保在将静态变量使用到翻译单元之前对其进行初始化。为了安全起见,请使用类似于singleton模式且众所周知的方法来解决该问题。它之所以有效,是因为:

    • 所有静态对象都是在任何xml_stuff实例的完整构造之后完全构造的
    • 在C++中静态对象的销毁顺序与它们的构造完成正好相反(当它们的构造函数完成执行)。 代码:

      现在,xml\u stuff::get\u memberN()返回的对象在任何xml\u stuff实例的整个生命周期内都是有效的,因为这些成员都是在任何xml\u stuff实例之前构造的。使用纯静态数据成员,不能保证,因为在C++中,跨翻译单元的创建顺序在C中没有定义。 在执行开始时,我希望从 XML文件并将其分配给 此类的数据成员。那些 值在整个过程中不会更改 执行,它们必须共享 由 有问题的班级

      黑体字的句子是这里的关键。只要该语句成立,就可以使用静态变量。这将如何实施


      很难理解。因此,如果你现在使用的说法总是正确的,那就继续吧。如果您希望将来的某个开发人员(或您)在错误地使用您的类(如在程序的中途读取另一个XML文件)时也使用相同的类,请执行Rasmus Farber所说的操作。

      这些值是在执行开始时设置的,因此这些问题在这里并不真正适用。David,一旦您决定将xml对象作为静态对象放在某个地方,它们就会出现。此外,销毁顺序也是相关的。请看下面我的答案。每当我读到“xxx不好”时,我的简化检测器就会开始闪烁。和其他海报一样,我相信使用静态变量是完全正确的。如果全局状态发生变化,那么它基本上是不好的。不变的全球状态,就是这样,工作得很好;它说,如果单例(和大致相当的全局状态)包含不可变的数据,那么它们不会造成任何损害,这很可能是。但是Diego问道:“静态数据成员是实现这种行为的最优雅的方式吗?”,而使用全局状态肯定不优雅。它是有效的,实际上可能不会给您带来任何问题,但它并不优雅。@David:如果它是从XML文件中读取的,那么它不是不变的。它在运行时可能不会改变,但这不是Misko在文章中提到的那种不变性。
      class xml_stuff {
      public:
          xml_stuff() {
              // 1. touch all members once
              // => 2. they are created before used
              // => 3. they are created before the first xml_stuff instance
              // => 4. they will be destructed after the last xml_stuff instance is 
              //       destructed at program exit.
              get_member1();
              get_member2();
              get_member3();
              // ...
          }  
      
          // the first time their respective function is called, these
          // objects will be created and references to them are returned.
          static type1 & get_member1() { static type1 t; return t; }
          static type2 & get_member2() { static type2 t; return t; }
          static type1 & get_member3() { static type1 t; return t; }
          // ... all other 7 members
      };