简体   繁体   中英

mt19997 C++ object passed by reference always generates the same values

I'm trying to write a code where I create an object mt19937 in a class A that can be used in the class internal functions for generating random numbers and I also want to pass a reference to this same object to various instances of the class B declared inside of the class A. Those objects passed through reference should be able to also generate random numbers for internal use in the class B.

The problem is: in the class A it generates random numbers, but the class B it generates the same sequences.

I have a code separated in three files like the example:

Class A

Ah:

#include <random>
#include <vector>
#include "B.h"

using namespace std;

class A
{
    public:
        A();
    private:
        mt19937 mt;
};

A.cpp:

#include "A.h"

A::A() : mt((random_device())())
{
    vector<B> Bs;

    for(int i = 0; i < 10; i++)
    {
        Bs.emplace_back(i, mt);
    }
}


Class B

Bh:

#include <random>
#include <iostream>

using namespace std;

class B
{
    public:
        B(int id, mt19937& mt);
    private:
        int id;
        mt19937 mt;
};

B.cpp:

#include "B.h"

B::B(int id, mt19937& mt)
{
    this->id = id;
    this->mt = mt;

    bernoulli_distribution dist(0.5);
    cout << "Testing random..." << endl;
    for(int i = 0; i < 10; i++)
    {
        cout << dist(this->mt) << " ";
    }
    cout << endl;
}

main

main.cpp:

#include "A.h"

int main()
{
    A a;
    return 0;
}

I don't know if it can help, but I'm compiling it like this:

g++-12 B.cpp A.cpp main.cpp -o main -std=c++17

and my computer is a Macbook Pro M1 running a Mac OS Monterey 12.2.1

I tried generating a random sequence of numbers for each instance of B, but each instance is getting the same sequence.

You are passing a reference but storing it as an object, hence you are constructing a new "mt" to solve this (with references) you need to make the following changes in Bh :

#include <random>
#include <iostream>

using namespace std;

class B
{
    public:
        B(int id, mt19937& mt);
    private:
        int id;
        mt19937 &mt; //<--- we need a reference
};

Now in B.cpp you need to initialize the reference with a member initializer list:

#include "B.h"

B::B(int id, mt19937& mt) : mt(mt) // <-- initializer list
{
    this->id = id;
    // this->mt = mt; <-- we don't need this

    bernoulli_distribution dist(0.5);
    cout << "Testing random..." << endl;
    for(int i = 0; i < 10; i++)
    {
        cout << dist(this->mt) << " ";
    }
    cout << endl;
}

Hope it helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM