differential equations in c++, problems with Runge Kutta's Method - c++

I wrote a program in c++ that should solve differential equations. The problem is, it seems like it does not work well with ROOT. It compilates fine, but when I execute, this is what I get:
*** Break *** segmentation violation
===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================
#0 0x00007fc28193984a in __GI___waitpid (pid=7730, stat_loc=stat_loc
entry=0x7ffffe4ae000, options=options
entry=0) at ../sysdeps/unix/sysv/linux/waitpid.c:31
#1 0x00007fc2818b2ffb in do_system (line=<optimized out>) at ../sysdeps/posix/system.c:148
#2 0x00007fc2831d0954 in TUnixSystem::StackTrace() () from /usr/lib/root/libCore.so
#3 0x00007fc2831d29ec in TUnixSystem::DispatchSignals(ESignals) () from /usr/lib/root/libCore.so
#4 <signal handler called>
#5 0x0000000000405a8a in Runge_Kutta::Passo(double, VettoreLineare&, double) ()
#6 0x0000000000403b8a in main ()
===========================================================
The lines below might hint at the cause of the crash.
If they do not help you then please submit a bug report at
http://root.cern.ch/bugs. Please post the ENTIRE stack trace
from above as an attachment in addition to anything else
that might help us fixing this issue.
===========================================================
#5 0x0000000000405a8a in Runge_Kutta::Passo(double, VettoreLineare&, double) ()
#6 0x0000000000403b8a in main ()
===========================================================
This is my program
equazione_differenziale.c
#include "equazione_differenziale.h"
EqDifferenzialeBase :: EqDifferenzialeBase (FunzioneBase* f) {
_f=f;
};
Eulero :: Eulero (FunzioneBase*f) : EqDifferenzialeBase(f) {};
Runge_Kutta :: Runge_Kutta (FunzioneBase* f) : EqDifferenzialeBase(f) {};
VettoreLineare Eulero :: Passo (double t, VettoreLineare& x, double h) {
VettoreLineare vec(x.GetN());
vec=x+_f->Eval(t,x)*h;
return vec;
};
Protone :: Protone (double m, double q, double E0, double f, double lambda){
_m=m;
_q=q;
_E0=E0;
_f=f;
_lambda=lambda;
};
VettoreLineare Protone::Eval(double t, const VettoreLineare& v) const{
VettoreLineare y(v.GetN());
for(int i=0; i<v.GetN()/2; i++){
y.SetComponent(i, v.GetComponent(v.GetN()/2+i));
y.SetComponent(i+v.GetN()/2, (-1.)*(_q/_m)*_E0*sin(2*M_PI*(v.GetComponent(i)/_lambda)-2*M_PI*_f*t));
};
return y;
};
VettoreLineare Runge_Kutta::Passo(double t, VettoreLineare& v, double h){
VettoreLineare k1=_f->Eval(t,v);
VettoreLineare k2=_f->Eval(t+h/2.,v+k1*(h/2.));
VettoreLineare k3=_f->Eval(t+h/2.,v+k2*(h/2.));
VettoreLineare k4=_f->Eval(t+h,v+k3*h);
VettoreLineare y=v+(k1+k2*2.+k3*2.+k4)*(h/6.);
return y;
};
equazione_differenziale.h
#ifndef equazione_differenziale_h_
#define equazione_differenziale_h_
#include "Vettore.h"
#include <iostream>
#include <cmath>
class FunzioneBase {
public:
virtual VettoreLineare Eval(double t, const VettoreLineare& v) const=0;
};
class Protone: public FunzioneBase {
private:
double _m,_q,_E0,_f,_lambda;
public:
Protone(double m, double q, double E0, double f, double lambda);
virtual VettoreLineare Eval(double t, const VettoreLineare& v) const;
};
class EqDifferenzialeBase {
protected:
FunzioneBase* _f;
public:
EqDifferenzialeBase (FunzioneBase* f);
virtual VettoreLineare Passo (double t, VettoreLineare& x, double h)=0;
};
class Eulero : public EqDifferenzialeBase {
public:
Eulero (FunzioneBase* f);
virtual VettoreLineare Passo (double t, VettoreLineare& x, double h);
};
class Runge_Kutta: public EqDifferenzialeBase {
protected:
FunzioneBase* _f;
public:
Runge_Kutta (FunzioneBase* f);
virtual VettoreLineare Passo(double t, VettoreLineare& v, double h);
};
#endif
Vettore.h
#ifndef vettore_h_
#define vettore_h_
#include <iostream>
#include <cmath>
#include <fstream>
class Vettore {
protected:
unsigned int _N;
double * _v;
void Quicksort(unsigned int primo, unsigned int ultimo);
void Scambia (int a, int b);
public:
Vettore ();
Vettore (int N);
Vettore (int N, char* nomefile);
Vettore (const Vettore& v);
virtual void SetComponent (int i, double x);
void AddComponent (double x);
double GetComponent (int i) const;
void Print () const;
void Print (char* nomefile) const;
void Sort();
virtual int GetN() const;
Vettore& operator=(const Vettore & vetty);
~Vettore();
};
class VettoreLineare : public Vettore {
protected:
public:
VettoreLineare () : Vettore() {};
VettoreLineare (int N) : Vettore(N) {};
VettoreLineare (int N, char* nomefile) : Vettore(N, nomefile) {};
VettoreLineare (const Vettore& v) : Vettore(v) {};
VettoreLineare operator+(const VettoreLineare& v);
VettoreLineare operator*(double lambda);
VettoreLineare& operator=(const VettoreLineare& v);
virtual int GetN() const;
virtual void SetComponent(int i, double x);
};
Vettore.c
#include "Vettore.h"
//Default Constructor
Vettore :: Vettore () {
_N=0;
_v=NULL;
};
//N Constructor
Vettore :: Vettore (int N) {
_N=N;
_v=new double [_N];
for (int i=0; i<_N; i++)
_v[i]=0;
};
//N file-taken constructor
Vettore :: Vettore (int N, char* nomefile) {
_N=N;
_v=new double [_N];
std::ifstream input;
input.open(nomefile);
double dato;
input>>dato;
for(int i=0; i<N; i++){
_v[i]=dato;
input>>dato;
};
input.close();
};
//Copyconstructor
Vettore :: Vettore (const Vettore& V) {
_N=V.GetN();
_v=new double [_N];
for(int i=0; i<_N; i++)
_v[i]=V.GetComponent(i);
};
//Destructor
Vettore::~Vettore(){
delete[] _v;
};
//Set Component
void Vettore :: SetComponent (int i, double x) {
if (i>_N) {
std::cout<<"errore!"<<std::endl;
return ;
};
_v[i]=x;
};
//Get Component
double Vettore :: GetComponent (int i) const {
if (i>_N){
std::cout<<"errore!"<<std::endl;
return 0;
};
return _v[i];
};
//Add Component (aggiunge il valore desiderato nella coda del vettore)
void Vettore :: AddComponent (double x) {
double* a=new double [_N+1];
for(int i=0; i<_N; i++)
a[i]=_v[i];
a[_N]=x;
delete [] _v;
_v=a;
_N=_N+1;
};
//Print
void Vettore :: Print () const {
std::cout<<"Il vettore ha: "<<_N<<" componenti."<<std::endl;
for(int i=0; i<_N; i++)
std::cout<<_v[i]<<std::endl;
};
//Stampa su file
void Vettore :: Print (char* nomefile) const {
std::ofstream output;
output.open(nomefile);
output<<_N;
for(int i=0; i<_N; i++)
output<<_v[i]<<std::endl;
output.close();
};
//Get _N
int Vettore :: GetN () const {
return _N;
};
//Operatore di Assegnazione
Vettore & Vettore::operator =(const Vettore& vetty){
if (_v) delete [] _v;
_N=vetty.GetN();
_v=new double [_N];
for(int n; n<_N; n++)
_v[n]=vetty._v[n];
return *this;
};
//Algoritmo Quicksort
void Vettore :: Sort (){
Quicksort(0,GetN()-1);
};
void Vettore :: Quicksort (unsigned int primo, unsigned int ultimo) {
if(ultimo-primo<=1){
if (GetComponent(primo)>GetComponent(ultimo)) Scambia(primo, ultimo);
return;
}
double pivot= GetComponent(int((primo+ultimo)/2));
unsigned int basso= primo, alto=ultimo;
while(basso < alto) {
while (GetComponent(basso)<pivot) basso++;
while (GetComponent(alto)>pivot) alto--;
if(basso<alto) { Scambia(basso,alto); basso++;};
};
Quicksort(primo, basso-1);
Quicksort(basso, ultimo);
};
void Vettore :: Scambia(int a, int b){
double k;
k=_v[a];
_v[a]=_v[b];
_v[b]=k;
};
//Operatore somma fra vettori
VettoreLineare VettoreLineare::operator+ (const VettoreLineare& v){
VettoreLineare sum(v.GetN());
for(int i=0; i<_N; i++)
sum.SetComponent(i, _v[i]+v.GetComponent(i));
return sum;
};
//Operatore Moltiplicazione scalare
VettoreLineare VettoreLineare::operator* (double lambda){
for(int i=0; i<_N; i++)
_v[i]=_v[i]*lambda;
return *this;
};
//Operatore Assegnazione
VettoreLineare& VettoreLineare::operator= (const VettoreLineare& k){
if (_v) delete [] _v;
_N=k.GetN();
_v=new double [k.GetN()];
for (int i=0; i<_N; i++)
_v[i]=k.GetComponent(i);
return *this;
};
int VettoreLineare :: GetN() const {
return _N;
};
void VettoreLineare :: SetComponent(int i, double x) {
_v[i]=x;
};
main.c
#include "equazione_differenziale.h"
#include "Vettore.h"
#include "iostream"
#include "TGraph.h"
#include "TApplication.h"
#include "TCanvas.h"
#include "TAxis.h"
using namespace std;
int main () {
//PRIMO PUNTO
//Dichiarazione equazione
Protone* myProt=new Protone (1.67E-27, 1.60E-19, 1.E7, 0.2, 5.E8);
Runge_Kutta myKutta(myProt);
//Dichiarazione DatiIniziali
VettoreLineare DatiIniziali (2);
DatiIniziali.SetComponent(0, 0);
DatiIniziali.SetComponent(1,1E8);
//dichiarazione tempo
double t_min=0;
double h=1E-12;
//definizione variabili root
TApplication myApp("myApp",0,0);
TGraph* g = new TGraph();
//ciclo
for(int i=0;i<(1E-7-t_min)/h;i++){
double x,y;
x=t_min+i*h;
DatiIniziali= myKutta.Passo(x, DatiIniziali ,h);
y=DatiIniziali.GetComponent(0);
g->SetPoint(i,x,y);
};
//Run grafico
TCanvas *c=new TCanvas("C1","C1",1);
c->cd();
g->GetXaxis()->SetTitle("t[s]");
g->GetYaxis()->SetTitle("x[m]");
g->Draw("AL");
myApp.Run();
return 0;
};
The strange thing is that this program works on university computers, but it doesn't on neither of my two computers. I'm thinking this means I installed ROOT badly on both computers, but I sincerely wouldn't know how to proove it.

You declare
class EqDifferenzialeBase {
protected:
FunzioneBase* _f;
and
class Runge_Kutta: public EqDifferenzialeBase {
protected:
FunzioneBase* _f;
and then do
Runge_Kutta :: Runge_Kutta (FunzioneBase* f) : EqDifferenzialeBase(f) {};
and then use it as
VettoreLineare Runge_Kutta::Passo(double t, VettoreLineare& v, double h){
VettoreLineare k1=_f->Eval(t,v);
From these lines it should be pretty clear what goes wrong and where the segmentation violation originates. So get rid of the ghost that shadows the field you really want to use.
And as in the other answer, correct the scalar product of the vector class to the standard of the sum operator.

Related

Having Class object inside the Class ctor

How to properly use a class object (Point) inside my class (Segment) object that they both inheritoring from the class(Figure2D)?
The Figure.h file:
#include <math.h>
#include <ostream>
class Figure2D
{
private:
double x;
double y;
double length;
double height;
char* name = NULL;
public:
Figure2D(double l, double h, double x = 0, double y = 0);
Figure2D(Figure2D& f);
Figure2D();
virtual ~Figure2D();
const Figure2D& operator=(Figure2D& d);
void setName(const char*);
double getX()const;
double getY()const;
double getLength()const;
double getHeight()const;
const char* getName()const;
double Area()const;
double Perimeter()const;
void Shift(double dx, double dy);
void MoveTo(double newX, double newY);
void Resize(double newL, double newH);
void Scale(double Kx, double Ky);
bool isInside(Figure2D* P);//Point(P->getX(),P->getT()) lies inside the figure
void print()const;
friend std::ostream& operator<<(std::ostream& o, Figure2D& d);
};
The Point.h file:
#pragma once
#include "Figure2D.h"
class Point : public Figure2D {
public:
Point(const char* s,int x,int y) :Figure2D(0,0,x,y)
{
setName(s);
}
Point(){}
Point(const Point& other)
{
}
~Point() {}
};
The Segment.h file:
#pragma once
#include "Figure2D.h"
#include "Point.h"
class Segment : public Figure2D
{
public:
Segment(const char* s, Point& p1, Point& p2)
{
setName(s);
if (p1.getX() <= p2.getX() && p1.getY() <= p2.getY())
{
isLeftToRightSegment = true;
}
else
{
isLeftToRightSegment = false;
}
}
protected:
bool isLeftToRightSegment;
};
I cant make this code in the main.cpp properly:
Segment S("Segment PQ", P, Q);
Eventually i want to make shaps as(Point,Segment,Rectangle,Square,Circle) with the
Figure2D class

Calling class constructor inside another class using a pointer to a member function

I am trying to initialize an object of a class inside a member function of another class. The problem is that I need to pass a function pointer to the constructor. I do not know how I can make this. This is the error:
no matching function for call to ‘inheritance01::inheritance01(double (inheritance02::*&)(double))’
inheritance01 LT (func);
The code below shows the problem.
class Base01 {
public:
Base01(double (*)(double));
virtual double calc(double) = 0;
double (*ptr_fd() const)(double) { return ptr_fd_; }
private:
double (*ptr_fd_)(double);
};
Base01::Base01(double (*f)(double))
: ptr_fd_(f)
{
}
//----------------------------------------------------
class inheritance01 : public Base01 {
public:
inheritance01(double (*ptr_f)(double));
virtual double calc(double);
};
inheritance01::inheritance01(double (*pf)(double))
: Base01(pf)
{
}
double inheritance01::calc(double t) { return 2.0 * t; }
//###################################################
class Base02 {
public:
Base02(double);
virtual double solution(double, double) = 0;
double a() { return a_; };
private:
const double a_;
};
Base02::Base02(double aa)
: a_(aa)
{
}
//------------------------------------------------------
class inheritance02 : public Base02 {
public:
inheritance02(double, double);
virtual double solution(double, double);
//static double sol_aux (double);
private:
double sol_aux(double);
const double b;
//double (inheritance02::*fptrsol_aux)(double u) = &inheritance02::sol_aux;
typedef double (inheritance02::*fptr)(double u);
fptr func;
};
inheritance02::inheritance02(double aa, double bb)
: Base02(aa)
, b(bb)
{
//func = double (*sol_aux)(double);
//func = &inheritance02::sol_aux;
}
//--------------------------------------------------
double inheritance02::sol_aux(double u)
{
return (a() + b) / u;
}
//--------------------------------------------------
double inheritance02::solution(double x, double t)
{
//inheritance01 LT (&func);
//inheritance01 LT (this->func);
//inheritance01 LT (&fptrsol_aux);
inheritance01 LT(func); // Here is the problem
return LT.calc(x + t);
}
//########################################################
#include <iostream>
int main()
{
inheritance02 obj(1.0, 1.0);
double value = obj.solution(1.0, 1.0);
std::cout << "value = " << value << std::endl;
return 0;
}
As the comment by #Eljay says, you are creating a typedef for a pointer to member function here:
typedef double (inheritance02::*fptr)(double u);
However, the constructor of inheritance01 takes a regular function pointer as an argument:
inheritance01( double (*ptr_f)(double));
so this line:
inheritance01 LT(func); // Here is the problem
doesn't work because the types don't match up (pointer to member functions are not convertible to function pointers).
The easy fix would be to make func a regular function pointer, like this:
typedef double (*fptr)(double u);
and everything should work fine.
Here's a demo.
Although I am not able to declare the 'func_' parameter as const and private (I do not know how to return a std::function) the following code solves my problem:
#include <iostream>
#include <functional>
using namespace std;
class Base01
{
public:
Base01( std::function<double (double)> );
virtual double calc( double ) = 0;
//function<double (double)> func { return func_; }
function<double (double)> func;
private:
//const function<double (double)> func_;
};
Base01::Base01( function<double (double)> f) : func(f) {}
//----------------------------------------------------
class inheritance01:public Base01
{
public:
inheritance01( function<double (double)> );
virtual double calc( double );
};
inheritance01::inheritance01 (function<double (double)> f): Base01(f){}
double inheritance01::calc(double t) { return Base01::func(2.0*t); }
//###################################################
class Base02
{
public:
Base02(double);
virtual double solution(double, double) = 0;
double a(){return a_;};
private:
const double a_;
};
Base02::Base02(double aa): a_(aa) {}
//------------------------------------------------------
class inheritance02 : public Base02
{
public:
inheritance02( double, double );
virtual double solution(double, double);
private:
double sol_aux (double);
const double b;
};
inheritance02::inheritance02 (double aa, double bb)
: Base02(aa), b(bb)
{}
//--------------------------------------------------
double inheritance02::sol_aux(double u) { return (a()+b)/u; }
//--------------------------------------------------
double inheritance02::solution(double x, double y)
{
inheritance01 LT ( bind( &inheritance02::sol_aux, this, placeholders::_1) );
return LT.calc(x+y);
}
//########################################################
int main()
{
inheritance02 obj (1.0,1.0);
double value = obj.solution(1.0,1.0);
std::cout << "value = " << value << std::endl;
return 0;
}

Initialize class object like an array

I'm creating a custom vector class for a school project and I'd like to be able to initialize it like this:
vector x = { 2, 3, 4, 5 };
Is there any way to do this is C++?
Here is the header of my class:
class vector {
private:
int vsize;
int valloc;
double* values;
public:
vector() : vsize(0), valloc(0), values(nullptr) {}
vector(???);
vector(const vector& v);
int size() const { return vsize; };
int alloc() const { return valloc; };
void resize(int newsize);
void insert(double x);
void insert(double x, int index);
double* value() const { return values; };
double value(int index) const { return *(values + index - 1); }
};
You can support that by adding a constructor that takes a std::initialzer_list<double>.
vector(std::initializer_list<double> init) : vsize(init.size()),
valloc(init.size()),
values(new double[init.size()])
{
std::copy(init.begin(), init.end(), values);
}
You can make that a bit more flexible by using a template.
template <typename T>
vector(std::initializer_list<T> init) : vsize(init.size()),
valloc(init.size()),
values(new double[init.size()])
{
std::copy(init.begin(), init.end(), values);
}

using template classes above main giving error during function call in main

I am using a base class and a child class defined above main in main.cpp
this gives me an error of undefined reference FactoryTraversal::AddPoint::AddPoint(int const&, int const&, int)'
Here is the code:
#include <iostream>
#include <list>
#include <typeinfo>
#include <cmath>
enum traversal_type
{
TRAVERSAL = 0,
TRAVERSALMAX
};
template <class T>
class FactoryTraversal
{
public:
FactoryTraversal();
FactoryTraversal *CreateInstance(const traversal_type &type);
virtual ~FactoryTraversal();
const std::list<int>& GetIndices() const {return indices;}
int GetIndicesSize() const {return indices.size();}
virtual void AddPoint(const T &x, const T &y, int index);
protected:
std::list<int> indices;
};
template<class T>
class Traversal : public FactoryTraversal<T>
{
public:
Traversal();
void AddPoint(const T &x, const T &y, int index);
int GetResultXOR() const {return result_xor;}
private:
T coords_s[2];
T coords_e[2];
int result_xor;
void update_result(int index);
T calculate_distance(const T &x1, const T &x2, const T &y1, const T &y2);
};
template<class T>
Traversal<T>::Traversal():FactoryTraversal<T>()
{
//Do nothing
}
template<class T>
void Traversal<T>::AddPoint(const T &x, const T &y, int index)
{
if (0 == this->GetIndicesSize())
{
this->indices.push_front(index);
coords_s[0] = x; coords_s[1] = y;
coords_e[0] = x; coords_e[1] = y;
}
else
{
T d1 = this->calculate_distance(x,coords_s[0],y,coords_s[1]);
T d2 = this->calculate_distance(x,coords_e[0],y,coords_e[1]);
if (d1 < d2)
{
this->indices.push_front(index);
coords_s[0] = x; coords_s[1] = y;
}
else
{
this->indices.push_back(index);
coords_e[0] = x; coords_e[1] = y;
}
}
this->update_result(index);
}
template<class T>
T Traversal<T>::calculate_distance(const T &x1, const T &x2, const T &y1, const T &y2)
{
if (typeid(T) == typeid(int))
{
return std::min(std::abs(x1-x2),std::abs(y1-y2));
}
return 0;
}
template<class T>
void Traversal<T>::update_result(int index)
{
if (0 == this->GetIndicesSize())
result_xor = index;
else
result_xor ^= index;
}
template<class T>
FactoryTraversal<T>::FactoryTraversal()
{
indices.clear();
}
template<class T>
FactoryTraversal<T>::~FactoryTraversal()
{
//Do Nothing
}
template<class T>
FactoryTraversal<T>* FactoryTraversal<T>::CreateInstance(const traversal_type &type)
{
if (TRAVERSAL == type)
return new Traversal<T>();
else
return NULL;
}
FactoryTraversal<int> factory_traversal;
Traversal<int> *traversal = new Traversal<int>();
int main()
{
int T;
std::cin>>T;
int output[T];
for (int i = 0; i < T; ++i)
{
int N;
std::cin>>N;
FactoryTraversal<int> factory_traversal;
FactoryTraversal<int> *traversal = factory_traversal.CreateInstance(TRAVERSAL);
for (int j = 0; j < N; ++j)
{
int x, y;
std::cin>>x>>y;
traversal->AddPoint(x,y,j+1);
}
Traversal<int> *tmp = dynamic_cast<Traversal<int> *>(traversal);
if (tmp)
output[i] = tmp->GetResultXOR();
else
output[i] = 0;
}
for (int i = 0; i < T; ++i)
{
std::cout<<output[i]<<std::endl;
}
return 0;
}
Interfaces in C++ are called "abstract classes", and classes are abstract if they have at least one "pure virtual function". A function is a pure virtual function if it is prefixed with virtual and has a trailing =0 in its declaration. This is what you want for FactoryTraversal::AddPoint:
virtual void AddPoint(const T &x, const T &y, int index) = 0;
Now the derived class is expected to define it (and it does). Without AddPoint being pure virtual, you are forced to provide an implementation for it in the base class, which you could do simply as:
virtual void AddPoint(const T &x, const T &y, int index){}
This gives a "default" or fallback implementation for when a derived class chooses not to override the method. If it were pure virtual, the derived class is forced to define it, lest a call to it result in a compiler error (otherwise the derived class is also considered abstract).
Note that destructors should never be pure virtual. The way you have it right now is great; you unconsciously followed the rules I've outlined above.
Some other notes:
Variable length arrays are not legal C++, this is a compiler extension:
int output[T]; // T is read from command line
Use a vector instead:
std::vector<int> output(T);
You have memory leaks as-is. Use a managed pointer like unique_ptr so you don't have to worry about new and delete
I stated that you wanted AddPoint to be pure virtual and I mean it. You code won't compile if that's the first step you take, though. It looks like you merged a base class and a factory into one; split those out.
Putting it all together we can define our new base class as:
template<class T>
class TraversalBase
{
public:
virtual ~TraversalBase(){}
const std::list<int>& GetIndices() const {return indices;}
int GetIndicesSize() const {return indices.size();}
virtual void AddPoint(const T &x, const T &y, int index) = 0;
protected:
std::list<int> indices;
};
The derived class becomes (very little change, also notice the override keyword):
template<class T>
class Traversal : public TraversalBase<T>
{
public:
void AddPoint(const T &x, const T &y, int index) override;
int GetResultXOR() const {return result_xor;}
private:
T coords_s[2];
T coords_e[2];
int result_xor;
void update_result(int index);
T calculate_distance(const T &x1, const T &x2, const T &y1, const T &y2);
};
And our Factory class is much simplified:
template <class T>
struct FactoryTraversal
{
FactoryTraversal(){}
std::unique_ptr<TraversalBase<T>> CreateInstance(const traversal_type &type);
~FactoryTraversal(){}
};
Live Demo (C++11)

Multiple Type output in Polymorphism

I have a problem when i want to create a pure virtual function and assign to this multiple range of output formats (like int, double and char).
i wrote below code and it works only when i eliminate my abstract class which it's not thing that i want.
my code:
enter code here
//class DynamicArray
//{
// public:
// virtual void GetData(unsigned int s, int& d) = 0;
// virtual void SetData(unsigned int s, int& d) = 0;
//};
class DynamicArrayDouble//: public DynamicArray
{
private:
unsigned int m_Length;
double* arr;
public:
DynamicArrayDouble(unsigned int l)
{
m_Length = l;
arr = new double[m_Length];
}
void SetParam(unsigned int l)
{
m_Length = l;
arr = new double[m_Length];
}
void GetData(unsigned int s, double& d)
{
d = arr[s];
}
void SetData(unsigned int s, double& d)
{
arr[s] = d;
}
};
when i uncomment DynamicArray class and DynamicArrayDouble inherit it i face with some error. it should be noted, first time i try to use void* for second parameter for Set and Get methods, but again i receive some errors that i can't use this code style like this:
error: cannot declare variable 'd1' to be of abstract type 'DynamicArrayDouble'
and code of above error is:
class DynamicArray
{
public:
virtual void GetData(unsigned int s, void* d) = 0;
virtual void SetData(unsigned int s, void* d) = 0;
};
class DynamicArrayDouble: public DynamicArray
{
private:
unsigned int m_Length;
double* arr;
public:
DynamicArrayDouble(unsigned int l)
{
m_Length = l;
arr = new double[m_Length];
}
void SetParam(unsigned int l)
{
m_Length = l;
arr = new double[m_Length];
}
void GetData(unsigned int s, double* d)
{
*d = arr[s];
}
void SetData(unsigned int s, double* d)
{
arr[s] = *d;
}
};
int main()
{
DynamicArrayDouble d1(5);
double x=0;
for(unsigned int i=0;i<5;i++)
{
x = ((i+1.0)/2);
d1.SetData(i,&x);
}
for(unsigned int i=0;i<5;i++)
{
d1.GetData(i,&x);
cout << "Data " << i+1 << " is = " << x << endl;
}
return 0;
}
i write my codes in codeblocks.
i will appreciate your answer... Thank you.
You can't simply override
void func(some_pointer_type ptr);
with
void func(some_other_pointer_type ptr);
and same goes for references. Those are in fact considered to be completely unrelated if they don't match.
DynamicArrayDouble - this name tells me you should look into templates and not write the same code for all the types you'll need. This is how STL works. You'll completely avoid runtime polymorphism.
For starters:
template <typename T>
DynamicArray;