如何在 C++ 中有效地构造随机骰子
How to efficiently construct random dice in C++
我有一个classdieClass
代表六面骰子,我用<random>
来定数。这是头文件 die.h
:
#include <random>
#include <iostream>
class dieClass
{
public:
dieClass();
int getNum() const { return num; }
private:
int num;
static std::uniform_int_distribution<int> distribution;
};
这里是实现文件die.cpp
:
#include "die.h"
dieClass::dieClass()
{
static std::random_device rdevice{};
static std::default_random_engine generator{rdevice()};
num = distribution(generator);
}
std::uniform_int_distribution<int> dieClass::distribution{1, 6};
问题:如果我调用dieClass dice[5]
,我创建了五个default_random_engines
,还是只创建了一个,因为它是静态的?基本上,构建 百万 个骰子的最有效方法是什么?我可以在构造函数之外声明 generator
吗,就像我为 distribution
所做的那样?我不太明白 private 和 static 是做什么的。
编辑: 像这样重新排列似乎可以达到我想要的效果,尽管这可能不是最佳做法。我从 class 中提取了所有随机数生成代码并将其粘贴到实现文件中。现在我可以从函数 roll
.
调用 generator
dieClass.h
#include <iostream>
class dieClass
{
public:
die();
void roll();
int getNum() const { return num; }
private:
int num;
};
dieClass.cpp
#include <random>
#include "die.hpp"
std::random_device rdevice{};
std::default_random_engine generator{rdevice()};
std::uniform_int_distribution<int> distribution{1, 6};
dieClass::dieClass()
{
num = distribution(generator);
}
void dieClass::roll()
{
num = distribution(generator);
}
如果你要有数百万个骰子,我更喜欢你的第二个例子。拥有一个随机生成器会更有效率。但是,您可以将其封装在 class.
中,而不是骰子的全局随机数生成器
像静态变量一样,您应该avoid尽可能多地使用全局变量。可以将这个新生成器 class 的引用或指针注入到您的 dieClass
。只需更改构造函数以接受它。每当您想生成一个新号码时,只需调用新 class.
的方法即可
这是一个例子:
#include <random>
#include <iostream>
class RandomNumberGenerator
{
public:
RandomNumberGenerator() : mRd(), mGen(mRd()), mDis(1, 6) {}
~RandomNumberGenerator() = default;
inline int Generate() { return mDis(mGen); }
private:
std::random_device mRd;
std::mt19937 mGen;
std::uniform_int_distribution<int> mDis;
};
class dieClass
{
public:
dieClass(RandomNumberGenerator &gen) : mGenerator(gen), num(gen.Generate()) {}
int getNum() const { return num; }
void roll() { num = mGenerator.Generate(); }
private:
RandomNumberGenerator &mGenerator; //store as reference to avoid copying
int num;
};
这样,RandomNumberGenerator
class 负责生成随机数,而不是 dieClass
class。
工作版本here。
我有一个classdieClass
代表六面骰子,我用<random>
来定数。这是头文件 die.h
:
#include <random>
#include <iostream>
class dieClass
{
public:
dieClass();
int getNum() const { return num; }
private:
int num;
static std::uniform_int_distribution<int> distribution;
};
这里是实现文件die.cpp
:
#include "die.h"
dieClass::dieClass()
{
static std::random_device rdevice{};
static std::default_random_engine generator{rdevice()};
num = distribution(generator);
}
std::uniform_int_distribution<int> dieClass::distribution{1, 6};
问题:如果我调用dieClass dice[5]
,我创建了五个default_random_engines
,还是只创建了一个,因为它是静态的?基本上,构建 百万 个骰子的最有效方法是什么?我可以在构造函数之外声明 generator
吗,就像我为 distribution
所做的那样?我不太明白 private 和 static 是做什么的。
编辑: 像这样重新排列似乎可以达到我想要的效果,尽管这可能不是最佳做法。我从 class 中提取了所有随机数生成代码并将其粘贴到实现文件中。现在我可以从函数 roll
.
generator
dieClass.h
#include <iostream>
class dieClass
{
public:
die();
void roll();
int getNum() const { return num; }
private:
int num;
};
dieClass.cpp
#include <random>
#include "die.hpp"
std::random_device rdevice{};
std::default_random_engine generator{rdevice()};
std::uniform_int_distribution<int> distribution{1, 6};
dieClass::dieClass()
{
num = distribution(generator);
}
void dieClass::roll()
{
num = distribution(generator);
}
如果你要有数百万个骰子,我更喜欢你的第二个例子。拥有一个随机生成器会更有效率。但是,您可以将其封装在 class.
中,而不是骰子的全局随机数生成器像静态变量一样,您应该avoid尽可能多地使用全局变量。可以将这个新生成器 class 的引用或指针注入到您的 dieClass
。只需更改构造函数以接受它。每当您想生成一个新号码时,只需调用新 class.
这是一个例子:
#include <random>
#include <iostream>
class RandomNumberGenerator
{
public:
RandomNumberGenerator() : mRd(), mGen(mRd()), mDis(1, 6) {}
~RandomNumberGenerator() = default;
inline int Generate() { return mDis(mGen); }
private:
std::random_device mRd;
std::mt19937 mGen;
std::uniform_int_distribution<int> mDis;
};
class dieClass
{
public:
dieClass(RandomNumberGenerator &gen) : mGenerator(gen), num(gen.Generate()) {}
int getNum() const { return num; }
void roll() { num = mGenerator.Generate(); }
private:
RandomNumberGenerator &mGenerator; //store as reference to avoid copying
int num;
};
这样,RandomNumberGenerator
class 负责生成随机数,而不是 dieClass
class。
工作版本here。