Как использовать случайный движок C ++ 11 и равномерное распределение в конструкторе классов? - PullRequest
2 голосов
/ 21 апреля 2020

Моя цель - создать простую программу с кубиками разного количества сторон, каждая из которых имеет свой случайный движок и распределение. Мой код генерирует случайные числа, но все они огромные, и одни и те же числа генерируются для разных односторонних кубиков. Мой конструктор содержит std :: mt19937, std ::iform_int_distribution, начальное число и число сторон, которые передаются. Со всем в конструкторе, это не будет работать, но если я помещу начальное значение, случайный движок и распределение как stati c участников Я могу заставить его работать, но тогда у меня есть только одна раздача для всех моих костей.

// Die.h
#pragma once

#include <random>

class Die {
   private:
      int numSides;
      long int seed;
      std::mt19937_64 randomEngine;
      std::uniform_int_distribution<int> dieDist;
   public:
      explicit Die(int numSides);
      int roll();
};

// Die.cpp
#include "Die.h"
#include <ctime>
#include <iostream>

Die::Die(int numSides) : numSides(numSides) {
   seed = static_cast<long int>(std::time(nullptr));
   std::mt19937_64 randomEngine(seed);
   std::uniform_int_distribution<int> dieDist(1,numSides);
}

int Die::roll() {
   return dieDist(randomEngine);
}

// Die.h testing
#include <iostream>
#include "Die.h"

int main() {
   Die side4Die(4);
   Die side6Die(6);
   Die side8Die(8);
   Die side10Die(10);
   Die side12Die(12);
   Die side20Die(20);

   for (int i = 0; i < 20; i++) {
      std::cout << side4Die.roll() << "  ";
   }
   std::cout << "\n\n";

   for (int i = 0; i < 20; i++) {
      std::cout << side6Die.roll() << "  ";
   }
   std::cout << "\n\n";

   for (int i = 0; i < 20; i++) {
      std::cout << side8Die.roll() << "  ";
   }
   std::cout << "\n\n";
}

То, что я ожидал увидеть, это вывод 20 чисел от 1 до 4, 20 чисел 1–6, затем 20 чисел 1–8. Может ли кто-нибудь объяснить, как объявить генератор случайных чисел и равномерное распределение в заголовочном файле, а затем как определить их в файле реализации? Что я получаю, как выход три линии

* * 1689685134 1006 537902435 1526154843 2032953622 41384282 869520735 539700904 48774590 1118072656 740173846 588830575 1204807261 300732443 1167922011 1120805453 1840559451 1073257265 900590269 1598330246 535084483 1008 *

1 Ответ

2 голосов
/ 21 апреля 2020

Ваш Die конструктор объявляет две локальные переменные, randomEngine и dieDist, и они переопределяют (или скрывают) члены класса с одинаковыми именами - и поэтому они остаются унифицированными.

Вместо этого, чтобы настроить учеников, используйте код, подобный следующему:

Die::Die(int nSides) : numSides(nSides) // Best not to use the same name twice!
{
    seed = static_cast<long int>(std::time(nullptr));
    randomEngine = std::mt19937_64(size_t(seed)); // Argument really should be a size type.
    dieDist = std::uniform_int_distribution<int>(1, numSides);
}

Не стесняйтесь просить дальнейших разъяснений и / или объяснений.

Примечание: Поворот Предупреждения компилятора могут помочь обнаружить такие проблемы! Для вашего исходного кода clang-cl дает несколько из них:

предупреждение: объявление затеняет поле 'D ie' [-Wshadow]

...