我很想知道这件事。我听说全局变量很糟糕,它们会损害代码的可维护性,可用性,可重用性等。但在这种情况下,我该怎么办?也就是说,我有一个“伪随机数生成器”(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的其他对象不同的参数列表。如果,例如,这将是一个问题。我们想要为我们可以加载/保存的所有内容使用一个通用的“可保存”基类。那么该怎么办?消除常见的“可保存”基础,并且只采用一种约定来设置加载/保存例程(但这本身并不坏?Oy!)?
最好的解决方案是什么,避免了全局变量的敌对可维护性问题,但也没有遇到这些新问题?
或者实际上在这里使用全局是否可以,毕竟,“rand()”内置的工作原理是什么?但后来我听到我心中的那句小事说“但是......但是,但是,全局变形很糟糕!糟糕!”从我所读到的,似乎有充分的理由认为它们不好。但似乎避免它们会产生新的困难,比如这个。例如,避免使用全局变量似乎比避免使用“goto”更难。
答案 0 :(得分:3)
你的不情愿有一些好处。您可能希望替换另一个生成器进行测试,例如,它会发出包含一些边缘情况的确定性序列。
Dependency Injection是一种避免全局变量的常用方法。
答案 1 :(得分:0)
随机数生成器是可以全局化的事情之一。您可以将其视为:
-A RandomNumberFactory,一种使用全局工厂的设计模式,它为您构建随机数。工厂当然在语义上是恒定的(在C ++中你可以在内部使用关键字“mutable”,如果这对你来说意味着什么。)
- 一个全局常量(全局常量可以,对吧?),它为您提供对全局常量randomNumber的只读访问权限。 randomNumber恰好是非确定性的,但它是不变的,当然没有应用程序会写入它。
- 此外,可能发生的最坏情况是什么?在多线程应用程序中,您的RNG会产生非确定性行为吗?喘气。正如@Mark Ransom在上面指出的那样,是的,这实际上是一个缺点,因为它使测试更难。如果这是您关心的问题,您可以考虑将其写出来的设计模式。
答案 2 :(得分:0)
使用全局变量有时是有意义的。没有人能断然说你的代码不应该有任何全局变量,句点。
您做需要的是了解全局变量可能产生的问题。如果您的应用程序的逻辑需要全局变量并且可以从多线程环境调用它,那么 没有任何内在错误,但您必须注意使用锁定,互斥,和/或原子读/写以确保正确的行为。