Seeded rand () for C ++ class

I am working on a C ++ class that uses the rand() constructor in the constructor. I would really like this class to take care of itself in almost every way, but I'm not sure where the rand() seed is.

If I have a rand() seed in a constructor, it will be sown every time a new instance of my object type is created. Therefore, if I were to create 3 objects in a sequence, they would all be created in one second and therefore would have the same seed for rand() , creating accurate data for each of the three instances of the object.

I would like the rand() seed in the class code, instead of doing this in the main function of my program, before I create the object. I was thinking of making a static bool seeded; , which means that rand() has not yet been seeded, but I'm not sure how to initialize it to false when creating the class.

My idea is like

 myConstructor(){ if(!seeded){ srand(time(NULL)); seeded = true; } myVariable = rand()%maxVal; } 

I think this will work if I just can figure out how to initialize a static value to false at a time at the beginning of the program. I understand that changing this static value to true will go through all instances of the object, if it was static, and therefore will only perform the initial function the first time an object type is created.

+6
source share
5 answers

I think this will work if I just can figure out how to initialize a static value to false at a time at the beginning of the program.

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

Be sure to define seeded in the implementation file. Otherwise, each file that contains your header will receive its own definition of a static member, and it can also cause problems with the linker, as it can be defined more than once.

On the side of the note, if the static member is of the integral type, you can assign it at the point of declaration.

Another option would be this, and personally, I would prefer this for this task:

 my_class::my_class() { static bool seeded = false; if(!seeded) { srand(time(NULL)); seeded = true; } myVariable = rand() % maxVal; } 
+6
source

This problem is one of the problems using rand() . In C ++ 11, the <random> library was introduced, which solves this and other problems.

Instead of having one global (or stream) state for rand() , the new API gives you explicit control over the state of the RNG by encapsulating it in an object with semantics values.

You can save the state as a member variable or as a static member if you want all instances to share one or something else that makes sense for your use.

 #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'; } 

(The above example uses several C ++ 11 functions, except for <random> ; the <chrono> library for time, uniform initialization, and class initialization for non-static members.)

+5
source

Use a function of a static variable that is initialized only once:

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

The problem is similar to the problem of instantiating a singleton. Use your OS function, such as pthread_once or boost::call_once , and a static member to run the seed and only once.

+1
source

Bames53 had a great answer. Now, so that all this fits well into the autonomous function of generating an integer:

 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
source

All Articles