静态随机数生成器丢失全局变量的种子
Static random number generator losing seed for global variable
我想做一个简单的方法来获取随机数,但是,gen,随机数生成器似乎在函数之间丢失了它的种子。如果你多次 运行 这个例子,你会看到生成的第一个随机数每次 运行 都是随机的,而第二个则不是。这是什么原因?
main.cpp
#include <iostream>
#include "Random.hpp"
class Global
{
public:
Global()
{
Random::seed();
std::cout << "\n" << Random::getRandom(-10, 10);//random
}
void Global::doStuff()
{
std::cout << "\n" << Random::getRandom(-10, 10);//not random
}
};
Global globalInstance;
int main()
{
globalInstance.doStuff();
return 0;
}
Random.hpp
#pragma once
#include <random>
class Random
{
public:
static void seed();
static int getRandom(int minInclusive, int maxInclusive);
private:
static std::default_random_engine gen;
static std::uniform_int_distribution<int> ints;
};
Random.cpp
#include "Random.hpp"
#include <time.h>
std::default_random_engine Random::gen;
std::uniform_int_distribution<int> Random::ints;
void Random::seed()
{
gen.seed(static_cast<unsigned int>(time(NULL)));
}
int Random::getRandom(int minInclusive, int maxInclusive)
{
std::uniform_int_distribution<int>::param_type range(minInclusive, maxInclusive);
ints.param(range);
return ints(gen);
}
您显示的代码似乎依赖于 random.cpp
中的静态范围对象在 main.cpp
中的静态范围对象之前实例化。
这是未定义的行为。 C++ 标准不保证来自不同翻译单元的静态范围对象的相对实例化顺序。
似乎正在发生的事情是,您的实现首先实例化了 main.cpp
的静态对象,它在 random.cpp
翻译单元中定义的对象中设置了随机种子。这本身包含未定义的行为,但这个操作似乎没有崩溃。
在 main.cpp
的静态对象被实例化后,random.cpp
的静态对象被实例化,从而将它们重置为使用默认种子值。
我想做一个简单的方法来获取随机数,但是,gen,随机数生成器似乎在函数之间丢失了它的种子。如果你多次 运行 这个例子,你会看到生成的第一个随机数每次 运行 都是随机的,而第二个则不是。这是什么原因?
main.cpp
#include <iostream>
#include "Random.hpp"
class Global
{
public:
Global()
{
Random::seed();
std::cout << "\n" << Random::getRandom(-10, 10);//random
}
void Global::doStuff()
{
std::cout << "\n" << Random::getRandom(-10, 10);//not random
}
};
Global globalInstance;
int main()
{
globalInstance.doStuff();
return 0;
}
Random.hpp
#pragma once
#include <random>
class Random
{
public:
static void seed();
static int getRandom(int minInclusive, int maxInclusive);
private:
static std::default_random_engine gen;
static std::uniform_int_distribution<int> ints;
};
Random.cpp
#include "Random.hpp"
#include <time.h>
std::default_random_engine Random::gen;
std::uniform_int_distribution<int> Random::ints;
void Random::seed()
{
gen.seed(static_cast<unsigned int>(time(NULL)));
}
int Random::getRandom(int minInclusive, int maxInclusive)
{
std::uniform_int_distribution<int>::param_type range(minInclusive, maxInclusive);
ints.param(range);
return ints(gen);
}
您显示的代码似乎依赖于 random.cpp
中的静态范围对象在 main.cpp
中的静态范围对象之前实例化。
这是未定义的行为。 C++ 标准不保证来自不同翻译单元的静态范围对象的相对实例化顺序。
似乎正在发生的事情是,您的实现首先实例化了 main.cpp
的静态对象,它在 random.cpp
翻译单元中定义的对象中设置了随机种子。这本身包含未定义的行为,但这个操作似乎没有崩溃。
在 main.cpp
的静态对象被实例化后,random.cpp
的静态对象被实例化,从而将它们重置为使用默认种子值。