Sending rand () для класса C ++

Я работаю над классом C ++, который использует rand() в конструкторе. Мне бы очень хотелось, чтобы этот класс позаботился о себе почти во всех отношениях, но я не уверен, где посеять rand(),

Если я семя rand() в конструктор он будет добавляться каждый раз, когда создается новый экземпляр типа моего объекта. Поэтому, если бы я создал 3 объекта в последовательности, все они были бы созданы в одну секунду и, следовательно, имели бы одинаковое начальное число для rand()создавая одинаковые данные для каждого из 3 экземпляров объекта.

Я хотел бы посеять rand() в коде класса, вместо того, чтобы делать это в основной функции моей программы перед созданием объекта. Я думал сделать static bool seeded; переменная, которая показывает, является ли rand() был посеян, но я не совсем уверен, как инициализировать его как false при создании класса.

Моя идея звучит примерно так

myConstructor(){
if(!seeded){
srand(time(NULL));
seeded = true;
}

myVariable = rand()%maxVal;
}

Я думаю, что это сработало бы, если бы я мог просто выяснить, как инициализировать статическое значение в false один раз в начале программы. Насколько я понимаю, изменение этого статического значения на true будет распространяться на все экземпляры объекта, если оно будет статическим, и, следовательно, будет выполнять начальную функцию только при первом создании этого типа объекта.

6

Решение

Я думаю, что это сработало бы, если бы я мог просто выяснить, как инициализировать статическое значение в false один раз в начале программы.

// my_class.h
class my_class {
public:
// ...
private:
static bool seeded;
};

// my_class.cpp
bool my_class::seeded = false;

Убедитесь, что определили seeded в файле реализации. В противном случае каждый файл, содержащий ваш заголовок, получит свое собственное определение статического члена, что также может вызвать проблемы с компоновщиком, так как он может быть определен более одного раза.

Напомним, что если статический член имел константный целочисленный тип, вы можете назначить его в точке объявления.

Другим вариантом было бы это, и лично я предпочел бы это для этой задачи:

my_class::my_class()
{
static bool seeded = false;
if(!seeded) {
srand(time(NULL));
seeded = true;
}

myVariable = rand() % maxVal;
}
6

Другие решения

Эта проблема является одной из проблем использования rand(), C ++ 11 представил <random> библиотека, которая решает эту и другие проблемы.

Вместо того, чтобы иметь единственное глобальное (или на поток) состояние для rand() Новый API дает вам явный контроль над состоянием ГСЧ, инкапсулируя его в объект с семантикой значений.

Вы можете поддерживать состояние как переменную-член или как статический член, если хотите, чтобы все экземпляры разделяли его, или что-либо еще, что имеет смысл для вашего использования.

#include <random> // for mt19937, uniform_int_distribution
#include <chrono> // for high_resolution_clock
#include <iostream>

struct C {
// Hold RNG state as a member variable
std::mt19937 eng{std::chrono::high_resolution_clock::now().time_since_epoch().count()};

int foo() {
// use the member variable to generate random numbers in a member function.
return std::uniform_int_distribution<>(1,10)(eng);
}
};

int main() {
C c, d;
std::cout << c.foo() << '\n';
std::cout << d.foo() << '\n';
}

(Выше используется несколько функций C ++ 11, кроме <random>; <chrono> библиотека для времени, равномерной инициализации и инициализации в классе для нестатических элементов.)

5

Используйте функцию статической переменной, которая инициализируется только один раз:

static bool seed()
{
srand(time(NULL));
return true;
}
myConstructor(){
static bool seeded = seed();
myVariable = rand()%maxVal;
}
2

Проблема похожа на проблему синглтон-инстанцирования. Используйте функцию вашей ОС, например pthread_once или же boost::call_once и static член для выполнения семян один и только один раз.

1

У bames53 был отличный ответ. Теперь, чтобы сделать все это в отдельную целочисленную функцию:

int generateRandom(int min, int max) {
std::mt19937 eng{std::chrono::high_resolution_clock::now().time_since_epoch().count()};
return std::uniform_int_distribution<>(min,max)(eng);
}
0
По вопросам рекламы [email protected]