C++ 如何在C++;

C++ 如何在C++;,c++,private,static-methods,private-members,random-seed,C++,Private,Static Methods,Private Members,Random Seed,我有一个类dieClass来表示一个六面模具,我使用来设置数字。这是头文件die.h: #include <random> #include <iostream> class dieClass { public: dieClass(); int getNum() const { return num; } private: int num; static std::uniform_int_distribution<int>

我有一个类
dieClass
来表示一个六面模具,我使用
来设置数字。这是头文件
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;
};
问题:如果我调用
dieClass dice[5]
,我是否创建了五个
默认随机引擎,还是仅仅创建了一个,因为它是静态的?基本上,构建数百万个骰子的最有效方法是什么?我可以在构造函数之外声明
generator
,就像我在
发行版中声明的那样吗?我不完全理解private和static做什么

编辑:重新安排这样的事情似乎达到了我想要的效果,尽管这可能不是最佳做法。我从类中提取所有随机数生成代码,并将其粘贴到实现文件中。现在我可以从函数
roll
调用
generator

dieClass.h
#include <iostream>

class dieClass
{
public:
    die();
    void roll();
    int getNum() const { return num; }

private:
    int num;
};
dieClass.h
#包括
第二类
{
公众:
模具();
空辊();
int getNum()常量{return num;}
私人:
int-num;
};
dieClass.cpp
#包括
#包括“die.hpp”
std::随机设备{};
std::默认的随机引擎生成器{rdevice()};
均匀分布{1,6};
dieClass::dieClass()
{
num=分配(发电机);
}
void类::roll()
{
num=分配(发电机);
}

如果你将有数百万个骰子,我更喜欢你的第二个例子。有一个随机发生器会更有效。但是,您可以将骰子封装在类中,而不是使用全局随机数生成器

与静态变量一样,您应该尽可能多地使用全局变量。可以将指向此新生成器类的引用或指针注入到您的
dieClass
。只需更改构造函数以接受它。无论何时,只要调用新类的一个方法,就可以生成一个新的数字

下面是一个例子:

#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():mRd(),mGen(mRd()),mDis(1,6){
~RandomNumberGenerator()=默认值;
内联int Generate(){返回MDI(mGen);}
私人:
std::随机_装置mRd;
标准:mt19937 mGen;
标准:统一内部分布MDI;
};
第二类
{
公众:
dieClass(RandomNumberGenerator&gen):mGenerator(gen),num(gen.Generate()){}
int getNum()常量{return num;}
void roll(){num=mGenerator.Generate();}
私人:
RandomNumberGenerator&mgGenerator;//存储为引用以避免复制
int-num;
};
这样,
RandomNumberGenerator
类负责生成随机数,而不是
dieClass


工作版本。

这是否回答了您的问题?它是静态的,所以它只是一个实例。我个人的方法是不使用静态成员,而是让die类有一个生成器、一个分布和函数来“抛出”die,从而生成一个新的随机数。您当前的方法似乎是模拟掷骰的结果,而不是可以多次掷骰的实际骰子。但这只是我的观点,我会选择
intgetnum(){returndistribution(generator);}
方法。为什么一个类需要数百万个实例,而这个类只会为您随机分配一个数字?只需调用一个函数,每次返回不同的随机值。这些成员不应该是静态的。将生成器重新用于多个模具对象完全违背了首先使用
random
的目的。如果您想共享这些,那么,您可以只共享一个
dieClass
的对象。稍微有点OT,但是在当前时间播种PRNG是一种危险的做法,只有当PRNG与安全性完全没有连接时才可以。对于一个纯粹的本地游戏来说,这很好。但当游戏允许人们上传他们的高分时,依赖时钟的种子就允许作弊。如果您需要任何质量的随机数,请使用
/dev/uradom
或类似的随机数。
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);
}
#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;
};