I would like to return an array to a pointer, in a virtual function that is a member of a derived class of a template class. In details, my classes definition is:
Sampler.h
#ifndef SAMPLER_H
#define SAMPLER_H
template <class T>
class Sampler
{
public:
virtual T getnumber()=0;
virtual T* simulation(int n)=0;
};
class UniformSampler:public Sampler<double>
{
public:
virtual double getnumber();
virtual double* simulation(int n);
UniformSampler(double a=0.0, double b=1.0);
private:
double low_bound;
double up_bound;
};
#endif
The class Sampler is a template class in order to be able to derive an other sampler with vectors later. The implementation is:
Sampler.cpp
#include "Sampler.h"
#include<iostream>
#include<cstdlib>
#include<cmath>
using namespace std;
//Uniform
UniformSampler::UniformSampler(double a, double b)
{
low_bound=a;
up_bound=b;
}
double UniformSampler::getnumber()
{
int myrand=rand();
while((myrand==0)||(myrand==RAND_MAX)){myrand = rand(); } //We want a number in (0, RAND_MAX).
double myuni = myrand/static_cast<double>(RAND_MAX); //Create a number in (0,1).
return low_bound + myuni*(up_bound-low_bound);
}
double* UniformSampler::simulation(int n){
double simulations[n];
for(int i=0; i<n; i++){
simulations[i] = this->getnumber();
}
return simulations;
}
My problem is that, when I try to call this program in the main(), it looks like the assignment of the pointer doesn't work. Here is my main.cpp:
#include <iostream>
#include <math.h>
#include <cstdlib>
#include <time.h>
using namespace std;
#include "Sampler.h"
int main(){
srand(time(0));
int n=10;
double *unif = new double[n];
UniformSampler uni;
unif = uni.simulation(n);
for ( int i = 0; i < n; i++ ) {
cout << "*(p + " << i << ") : ";
cout << *(unif + i) << endl;
}
delete[] unif;
return 0;
}
When I run it, it doesn't print any of the elements that unif points to. I don't understand what is wrong there.
UniformSampler::simulation is twice wrong:
double simulations[n]; uses VLA extension, so not C++ standard compliant.
you return pointer on local variable, so dangling pointer.
Solution: use std::vector instead.
#include <vector>
template <class T>
class Sampler
{
public:
virtual ~Sampler() = default;
virtual T getnumber() = 0;
virtual std::vector<T> simulation(int n) = 0;
};
class UniformSampler:public Sampler<double>
{
public:
explicit UniformSampler(double a=0.0, double b=1.0);
double getnumber() overrid;
std::vector<double> simulation(int n) override
{
std::vector<double> res(n);
for (auto& val : res){
res = getnumber();
}
return res;
}
private:
double low_bound;
double up_bound;
};
int main(){
srand(time(0));
constexpr int n = 10;
UniformSampler uni;
auto unif = uni.simulation(n);
for (int i = 0; i < n; i++ ) {
std::cout << "p[" << i << "]: " << unif[i] << endl;
}
}
Related
class A
{
int id;
public:
A (int i) { id = i; }
void show() { cout << id << endl; }
};
int main()
{
A a[2];
a[0].show();
a[1].show();
return 0;
}
I get an error since there is no default constructor.However thats not my question.Is there a way that ı can send parameters when defining
A a[2];
A good practice is to declare your constructor explicit (unless it defines a conversion), especially if you have only one parameter. Than, you can create new objects and add them to your array, like this :
#include <iostream>
#include <string>
class A {
int id;
public:
explicit A (int i) { id = i; }
void show() { std::cout << id << std::endl; }
};
int main() {
A first(3);
A second(4);
A a[2] = {first, second};
a[0].show();
a[1].show();
return 0;
}
However, a better way is to use vectors (say in a week you want 4 objects in your array, or n object according to an input). You can do it like this:
#include <iostream>
#include <string>
#include <vector>
class A {
int id;
public:
explicit A (int i) { id = i; }
void show() { std::cout << id << std::endl; }
};
int main() {
std::vector<A> a;
int n = 0;
std::cin >> n;
for (int i = 0; i < n; i++) {
A temp(i); // or any other number you want your objects to initiate them.
a.push_back(temp);
a[i].show();
}
return 0;
}
I am trying to access the elements of a virtual function which is declared in Class 1 and then defined in Class 2. I understand that the std :: out_of_range error is a memory access problem, but I don't understand the problem in the code main () to access the values.
When calling the function ** m-> function (t, j) ** I cannot access the elements of * parmem *, but if I directly call the output of the function it works: ** parmem.at (1). gamma **. Here is the code:
Class 1:
#include <armadillo>
#include <iostream>
using namespace std;
using namespace arma;
class Class1
{
public:
mat Y;
struct Par
{
mat gamma;
} par;
std::vector<Par> parmem ;
virtual double function( const int t, const int j ) = 0;
};
Class 2:
class Class2 : public Class1
{
public:
virtual double function( const int t, const int j );
};
double Class2::function( const int t, const int j )
{
cout << parmem.at(t).gamma << endl;
return j+t;
}
main()
int main()
{
mat Y=randu<mat>(3,3);
int t=1;
int j=1;
Class2 *m = new Class2;
std::vector<Class1::Par> parmem {
{Y},
{2*Y}
};
cout << parmem.at(1).gamma << endl; //funciona
cout << m->function(t,j) << endl; //no funciona
return 0;
}
Thanks for the info.
In the following lines, you create independent objects:
Class2 *m = new Class2;
std::vector<Class1::Par> parmem {
{Y},
{2*Y}
};
The std::vector<Class1::Par> parmem {{Y},{2*Y}}; is not part of the instance of the object m is pointing at.
It should work if you assign parmem to the object m points on by adding m->parmem = paramen; to the code.
int main()
{
mat Y=randu<mat>(3,3);
int t=1;
int j=1;
Class2 *m = new Class2;
std::vector<Class1::Par> parmem {
{Y},
{2*Y}
};
m->parmem = paramen;
cout << parmem.at(1).gamma << endl; //funciona
cout << m->function(t,j) << endl; //no funciona
return 0;
}
I need help... appropriate questions have been asked in the comments. The programs has zero compiler errors and warnings!! I have concerns with calling a member function from another member function using function pointers. (To be precise, setMatrixto() is trying to call setElement() function using function pointer)
Plus somehow the "hello there" is not being printed to the console. I was expecting it to show up as output.Maybe the setMatrixto() is not getting called at all!!
Header File definition
#ifndef MATRIXOPERATIONS_H
#define MATRIXOPERATIONS_H
class MatrixOperations;
typedef int (MatrixOperations::*INTFUNC)(int,int);
typedef void (MatrixOperations::*VOIDFUNC)(int,int,int);
class MatrixOperations
{
public:
MatrixOperations();
MatrixOperations(int size);
~MatrixOperations();
//diagonal matrix funtions
void displayMatrixOf(INTFUNC f);
void setMatrixTo(VOIDFUNC f);
int getElement(INTFUNC from, int i, int j);
void setElement(VOIDFUNC to,int i ,int j, int value);
int fromDiagonalArray(int i, int j);
void toDiagonalArray(int i, int j, int value);
protected:
private:
int size;
int* a;
};
#endif // MATRIXOPERATIONS_H
CPP Implementation File
#include "MatrixOperations.h"
#include <iostream>
using namespace std;
MatrixOperations::MatrixOperations()
{
//ctor
size = 3;
a = new int[size];
}
MatrixOperations::MatrixOperations(int size)
{
//ctor
this->size = size;
a = new int[size];
}
MatrixOperations::~MatrixOperations()
{
//dtor
delete[] a;
}
///////////////////FUCNTION POINTER SECTION///////////////////////////////////
int MatrixOperations::getElement(INTFUNC from, int i, int j)
{
return (this->*from)(i,j);
}
void MatrixOperations::setElement(VOIDFUNC to,int i ,int j, int value)
{
(this->*to)(i,j,value);
}
/////////////////////////////////DIAGONAL ARRAY OPERATIONS/////////////////////////////////////////////////
int MatrixOperations::fromDiagonalArray(int i, int j)
{
if(i==j)
{
return a[i];
}
else
{
return 0;
}
}
void MatrixOperations::toDiagonalArray(int i, int j, int value)
{
a[i] = value;
}
///////////////////////////////////////////////////////////////////
void MatrixOperations::displayMatrixOf(INTFUNC f)
{
for(int i{0}; i < size; i++)
{
for(int j{0}; j < size; j++)
{
cout << getElement(f,i,j) << "\t"; //is this the correct way to send the function pointer?
}
cout << endl;
}
}
void MatrixOperations::setMatrixTo(VOIDFUNC f)
{
cout << "Hello there!!"; //not getting this output.. whats wrong??
for(int i{0}; i < size; i++)
{
int value {};
cout << "Enter value diagonal element " << i << " : ";
cin >> value;
setElement(f,i,i,value); //is this the correct way to send the function pointer?
}
}
///////////////////////////////////////////////////////////////////////////////
Main File
#include <iostream>
#include "MatrixOperations.h"
typedef MatrixOperations MATRIX;
using namespace std;
int main()
{
MATRIX m1;
m1.setMatrixTo(MATRIX::toDiagonalArray); //was expecting a "Hello there!" but i am not getting that output either
return 0;
}
EDIT2: I added all the class definitions and main function in one single file. SURPRISINGLY!! this works . I am confused??!!!
#include <iostream>
using namespace std;
class MatrixOperations;
typedef void (MatrixOperations::*VOIDFUNC)(int,int,int);
typedef MatrixOperations MATRIX;
class MatrixOperations
{
public:
MatrixOperations();
MatrixOperations(int size);
~MatrixOperations();
//diagonal matrix funtions
void setMatrixTo(VOIDFUNC f);
void setElement(VOIDFUNC to,int i ,int j, int value);
void toDiagonalArray(int i, int j, int value);
private:
int size;
int* a;
};
MatrixOperations::MatrixOperations()
{ //ctor
size = 3;
a = new int[size];
}
MatrixOperations::MatrixOperations(int size)
{ //ctor
this->size = size;
a = new int[size];
}
MatrixOperations::~MatrixOperations()
{
//dtor
delete[] a;
}
void MatrixOperations::setElement(VOIDFUNC to,int i ,int j, int value)
{
(this->*to)(i,j,value);
}
/////////////////////////////////DIAGONAL ARRAY OPERATIONS/////////////////////////////////////////////////
void MatrixOperations::toDiagonalArray(int i, int j, int value)
{
a[i] = value;
}
///////////////////////////////////////////////////////////////////
void MatrixOperations::setMatrixTo(VOIDFUNC f)
{
cout << "Hello there!!" << endl;
for(int i{0}; i < size; i++)
{
int value {};
cout << "Enter value diagonal element " << i << " : ";
cin >> value;
setElement(f,i,i,value);
}
}
int main()
{
MATRIX m1;
m1.setMatrixTo(MATRIX::toDiagonalArray);
return 0;
}
There is nothing wrong with the code in both cases. Its just my debugger was not running in admin mode. I got error code 740. So I launched my IDE in admin mode and voila it worked.
What I am trying to do in this question is in line with what I was trying to do in: Dynamic Eigen vectors in Boost::odeint. However now I am trying to encapsulate it all in a class as follows:
#include <iostream>
#include <Eigen/Core>
#include <cstdlib>
#include <boost/numeric/odeint.hpp>
#include <boost/numeric/odeint/external/eigen/eigen_algebra.hpp>
namespace odeint = boost::numeric::odeint;
typedef odeint::runge_kutta_dopri5<Eigen::VectorXd, double, Eigen::VectorXd, double, odeint::vector_space_algebra> stepper;
class foo
{
private:
Eigen::VectorXd m_x;
Eigen::MatrixXd m_A;
double m_t, m_dt;
public:
foo(int nr_of_states){ //ctor
m_t = 0;
m_dt = 1.0;
m_x = Eigen::VectorXd(nr_of_states);
m_A = Eigen::MatrixXd(nr_of_states, nr_of_states);
srand(365);
for (int i = 0; i < m_A.size(); i++){
*(m_A.data()+i) = ((double)rand()/(double)RAND_MAX);}
for (int i = 0; i < m_x.size(); i++){
*(m_x.data()+i) = i;}
}
void ODE_function(const Eigen::VectorXd &x, Eigen::VectorXd &dxdt, double){
dxdt = m_A * x;}
void next_step(){
odeint::integrate_adaptive(stepper(), ODE_function, m_x, m_t, (m_t+(1*m_dt)), m_dt);}
Eigen::VectorXd get_states(){
return m_x;}
};
int main()
{
int nr_of_states;
std::cout << "How many (random) states would you like to simulate?: ";
std::cin >> nr_of_states;
std::cout << std::endl;
foo f1(nr_of_states);
for (int i = 0; i < 100; i++){
f1.next_step();}
std::cout <<std::endl << "final state vector: " << std::endl << f1.get_states() << std::endl;
return 0;
}
I am using the MinGW 64 bit compiler to compile above code when I get the following error message:
\boost\boost_1_59_0\boost\numeric\odeint\stepper\base\explicit_error_stepper_fsal_base.hpp|297|error:
must use '.' or '->' to call pointer-to-member function in 'sys
(...)', e.g. '(... ->* sys) (...)'|
Is what I am trying to do here in principle possible? If yes, how should above code be adapted?
In Class Dim I created array G and I want to pass it to the derived Class PHYS_FIELD. Instead of output (0..9) it gives (0..0). I realize that it is just a new copy of G but I do not know how to do it correctly.
arr1.h:
#ifndef ARR1_H
#define ARR1_H
#include<iostream>
using namespace std;
template <class T> class arr1
{
public:
T* data;
size_t size;
arr1(const size_t isize)
{ size=isize;
data = new T[size];
}
T & operator ()(size_t const index)
{ return data[index]; }
};
#endif /*ARR1_H */
dim.h:
#ifndef DIM_H
#define DIM_H
#include "arr1.h"
class DIM {
public:
DIM();
protected:
int N;
};
#endif /* DIM_H */
dim.cpp:
#include "arr1.h"
#include "dim.h"
using namespace std;
DIM :: DIM()
{
N=10;
arr1<double> G(N);
for (int i=0; i<N; i++)
G(i)=i;
};
phys_field.h:
#ifndef PHYS_FIELD_H
#define PHYS_FIELD_H
#include "dim.h"
#include "arr1.h"
class PHYS_FIELD : public DIM {
public:
PHYS_FIELD();
arr1<double> G;
};
#endif /* PHYS__FIELD_H */
phys_field.cpp:
#include "dim.h"
#include "phys_field.h"
#include <arr1.h>
using namespace std;
PHYS_FIELD :: PHYS_FIELD(): G(N) {
cout<< " from phys_field.cpp "<<endl;
cout<<N<<endl;
for (int i=0; i<N ; i++)
cout<<i<<" "<<G(i)<<endl;
};
main.cpp:
#include "dim.h"
#include "phys_field.h"
using namespace std;
int main(int argc, char* argv[]){
PHYS_FIELD *F= new PHYS_FIELD();
return 0;
}
modify class arr1 and add a constructor that accepts zero parameters (this way we can declare arr1 G and later build it in DIM::DIM constructor
arr1()
{
}
class DIM:
protected:
arr1<double> G; //I've moved G from the constructor so that PHYS_FIELD can inherit it directly
DIM::DIM()
{
N=10;
G = arr1<double>(N);
for (int i=0; i<N; i++)
G(i)=i;
};
class PHYS_FIELD
remove arr1<double> G; from PHYS_FIELD header so that it doesn't hide the G inherited from DIM
PHYS_FIELD::PHYS_FIELD() { //removed G(N)
cout << " from phys_field.cpp " << endl;
cout << N << endl;
for (int i=0; i<N; i++)
cout << i << " " << G(i) << endl;
};
Is this what you are looking for?