I am relatively new to C++ and I am having an issue with a very useful random number generator class that I programmed thanks to stackoverflow. I am using MS Visual Studio running on Windows 10. The original version works very well, but I would like to add two access functions: Get_Generator and Set_Generator. However, no matter how I try to do this I obtain the link error shown below. I am confused since I copied the format of the other, working member functions when I wrote these member functions. I'm sure I am making a simple mistake, but I cannot find anything online that will shed light onto my error. My apologies for the long code but I thought it important to see the full class definition(s) and the member functions.
Thanks for your time!
// Random_Num.h
#ifndef RANDOM_NUM_H
#define RANDOM_NUM_H
#ifdef _MSC_VER
#pragma once
#endif // _MSC_VER
#include <cstdlib> // standard Library
#include <random> // required for random number generation
#include <ctime> // to seed the generator with the clock
#include <chrono> // to seed the generator with the clock
//
// User Interface
//
class IRandom
{
public:
virtual double Ran_D() = 0; // random double on [0.0, 1.0)
virtual double Ran_D(double minValue, double maxValue) = 0; // random double on [minValue, maxValue)
virtual long long int Ran_I(long long int maxValue) = 0; // random integer on [0, maxValue]
virtual long long int Ran_I(long long int minValue, // random integer on [minValue, maxValue]
long long int maxValue) = 0;
virtual std::mt19937 Get_Generator() = 0; // Access function [minValue, maxValue]
virtual void Set_Generator(std::mt19937 G) = 0; // access function
};
// random number generation class, also in Random_Num.h
class Random_Num : public IRandom
{
private:
std::mt19937 _randomNumberGenerator;
std::uniform_real_distribution<double> _realDistribution;
public:
Random_Num(long long int seed); // constructor - initalize Mercent Twist enginge
virtual ~Random_Num(); // default destructor
double Ran_D(); // random double on [0,1)
double Ran_D(double minValue, double maxValue); // random double on [minValue,maxValue)
long long int Ran_I(long long int maxValue); // random integer on [0, maxValue]
long long int Ran_I(long long int minValue, long long int maxValue); // random integer on [minValue, maxValue]
std::mt19937 Get_Generator(); // Access function [minValue, maxValue]
void Set_Generator(std::mt19937 G); // access function
};
#endif
// Random_Num.cpp
#include "pch.h"
#include "Random_Num.h"
Random_Num::Random_Num(long long int seed) // constructor - initalize Mercent Twist enginge
{
this->_randomNumberGenerator = std::mt19937((long long int) seed);
this->_realDistribution = std::uniform_real_distribution<double>();
}
Random_Num::~Random_Num() { } // default destructor
double Random_Num::Ran_D() // random double on [0,1)
{
return this->_realDistribution(_randomNumberGenerator);
}
double Random_Num::Ran_D(double minValue, double maxValue) // random double on [minValue,maxValue)
{
std::uniform_real_distribution<double> distribution(minValue, maxValue);
return distribution(this->_randomNumberGenerator);
}
long long int Random_Num::Ran_I(long long int maxValue) // random integer on [0, maxValue]
{
return this->Ran_I(0, maxValue);
}
long long int Random_Num::Ran_I(long long int minValue, long long int maxValue) // random integer on [minValue, maxValue]
{
std::uniform_int_distribution<long long int> distribution(minValue, maxValue);
return distribution(this->_randomNumberGenerator);
}
std::mt19937 Random_Num::Get_Generator() // access function
{
return this->Random_Num::_randomNumberGenerator;
}
void Random_Num::Set_Generator(std::mt19937 G) // access function
{
this->Random_Num::_randomNumberGenerator = G;
}
// Main.cpp
long long int seed = (long long int) std::chrono::system_clock::now().time_since_epoch().count();
extern unique_ptr<IRandom> randomService = make_unique<Random_Num>(seed); // make random number generator a global variable
int main(int argc, char *argv[])
{
extern unique_ptr<IRandom> randomService;
std::mt19937 Gen;
double r;
long long int i;
r = randomService->Ran_D(); // returns random double on [0,1) - works fine
i = randomService->Ran_I(5); // returns random integer on [0,5] - works fine
Gen = randomService->IRandom::Get_Generator(); // Linker error
randomService->IRandom::Set_Generator(Gen); // Linker error
}
// Link error
error LNK2001: unresolved external symbol "public: virtual void __cdecl IRandom::Set_Generator(class std::mersenne_twister_engine<unsigned int,32,624,397,31,2567483615,11,4294967295,7,2636928640,15,4022730752,18,1812433253>)" (?Set_Generator@IRandom@@UEAAXV?$mersenne_twister_engine@I$0CA@$0CHA@$0BIN@$0BP@$0JJAILANP@$0L@$0PPPPPPPP@$06$0JNCMFGIA@$0P@$0OPMGAAAA@$0BC@$0GMAHIJGF@@std@@@Z)
error LNK2001: unresolved external symbol "public: virtual class std::mersenne_twister_engine<unsigned int,32,624,397,31,2567483615,11,4294967295,7,2636928640,15,4022730752,18,1812433253> __cdecl IRandom::Get_Generator(void)" (?Get_Generator@IRandom@@UEAA?AV?$mersenne_twister_engine@I$0CA@$0CHA@$0BIN@$0BP@$0JJAILANP@$0L@$0PPPPPPPP@$06$0JNCMFGIA@$0P@$0OPMGAAAA@$0BC@$0GMAHIJGF@@std@@XZ)
1>C:\Users\Bill2\source\repos\qcd\x64\Release\qcd.exe : fatal error LNK1120: 2 unresolved externals
1>Done building project "qcd.vcxproj" -- FAILED.
Aucun commentaire:
Enregistrer un commentaire