3

我想知道这个。我听说全局变量很糟糕,它们会损害代码的可维护性、可用性、可重用性等。但在这种情况下,我还能做什么呢?也就是说,我有一个“伪随机数生成器”(PRNG),众所周知,它们涉及一个内部状态,每次生成新的随机数时都会发生变化。但这似乎是一种需要全球化的东西!或者是 RNG 类的“静态”成员,但这本质上是一个全局的!全局变量很糟糕

那么,我能做些什么呢?显而易见的是有这样的东西(真的被剥离了):

class RNG {
      private:
          StateType state;              // this is the thing one may be tempted
                                        // to make "static", which ruins the
                                        // whole idea
      public:
          RNG();                        // constructor seeds the RNG
          ~RNG();
          int generateRandomInt();
};

但是我们需要播种好,如果我们要在每次需要某个函数或类中的随机数时创建一个实例。使用时钟可能不起作用,因为如果创建的两个“RNG”类型的实例太靠近会怎样?然后他们得到相同的种子并产生相同的随机序列。坏的。

我们还可以创建一个主 RNG 对象并用指针传递它(而不是使其成为全局对象,这会使我们回到第 1 格),以便需要随机数的类获得指向其中的 RNG 对象的指针。但后来我遇到了一个问题,涉及将这些对象保存/加载到磁盘/从磁盘加载——我们不能只为每个实例“保存 RNG”,因为我们只有一个 RNG 对象。相反,我们必须将 RNG 传递给加载例程,这可能会为这些例程提供与其他不使用 RNG 的对象不同的参数列表。如果我们想为我们可以加载/保存的所有内容使用一个通用的“可保存”基类,这将是一个问题。那么该怎么办?消除常见的“可保存”基础,只采用关于如何制作加载/保存例程的约定(但不是 本身就没有那么糟糕吗?哦!)?

避免全局变量的可维护性问题但又不会遇到这些新问题的最佳解决方案是什么?

或者实际上可以在这里使用全局变量,毕竟“rand()”内置函数就是这样工作的?但后来我听到我脑海里的那个小东西在说“但是……但是但是但是,全局变量很糟糕!糟糕!” 从我所读到的,似乎有相当充分的理由认为它们不好。但似乎避免它们会产生新的困难,比如这个。例如,避免全局变量似乎比避免“goto”更难。

4

3 回答 3

4

你的不情愿是有道理的。例如,您可能想要替换另一个生成器进行测试,它会生成一个包含一些边缘情况的确定性序列。

依赖注入是避免全局变量的一种流行方法。

于 2012-05-18T21:53:15.493 回答
1

随机数生成器是更适合全局的事物之一。你可以把它想象成:

-A RandomNumberFactory,一种使用全局工厂的设计模式,它为您构建随机数。工厂在语义上当然是恒定的(在 C++ 中,如果这对您意味着什么,您可以在内部使用关键字“可变”。)

- 一个全局常量(全局常量没问题,对吗?),它使您可以只读访问全局常量 randomNumber。randomNumber 恰好是不确定的,但它是恒定的,因为当然没有应用程序会写入它。

-此外,可能发生的最坏情况是什么?在多线程应用程序中,您的 RNG 会产生不确定的行为吗?喘气。正如@Mark Ransom 上面指出的那样,是的,这实际上是一个缺点,因为它使测试变得更加困难。如果这对您来说是一个问题,您可能会考虑一种将其写出来的设计模式。

于 2012-05-18T22:03:41.307 回答
0

有时使用全局变量是有意义的。没有人可以断然地说你的代码不应该有任何全局变量,句号。

需要了解全局变量可能引起的问题。如果您的应用程序的逻辑需要全局变量并且可以从多线程环境中调用它,那么这本身并没有什么问题,但是您必须小心使用锁定、互斥锁和/或原子读/写以确保正确的行为。

于 2012-05-18T22:06:04.623 回答