Why does GSL give error about mismatched dimension when there isn't one - c++

I'm wrapping GSL's ODE functions is a class I'm defining. When written with no class involved, the functions are working perfectly. However, when using the class I get an error after the second gsl_odeiv2_evolve_apply_fixed_step, getting the error gsl: evolve.c:317: ERROR: step dimension must match evolution size. I'm confused why the first step should work but the second shouldn't. In printing out the dimension of the step and evolve functions I get the same thing. Here's what I have for my class and what I'm calling inside the main() function.
class DynSys {
public:
DynSys(const size_t size, double startTime, double endTime, double stepSize,
double* iState,
int (*func)(double, const double*, double*, void*),
int (*jac)(double, const double*, double*, double*, void*),
const gsl_odeiv2_step_type* T = gsl_odeiv2_step_rk8pd)
: T(T), size(size), t(startTime), t1(endTime), h(stepSize) {
y = new double[size];
y = iState;
yPrev = new double[size];
s = gsl_odeiv2_step_alloc(T, size);
c = gsl_odeiv2_control_y_new(1e-6, 0.0);
e = gsl_odeiv2_evolve_alloc(size);
sys = { func, jac, size, 0 };
}
~DynSys() {
delete [] y;
delete [] yPrev;
gsl_odeiv2_evolve_free(e);
gsl_odeiv2_control_free(c);
gsl_odeiv2_step_free(s);
}
void step() {
printf("e dim: %ld\n", e->dimension);
printf("s dim: %ld\n", s->dimension);
printf("y: %.5f %.5f %.5f %.5f %.5f %.5f\n", y[0], y[1],
y[2], y[3], y[4], y[5]);
tPrev = t;
yPrev = std::copy(y, y+size, yPrev);
int status = gsl_odeiv2_evolve_apply_fixed_step(e, c, s, &sys,
&t, h, y);
if (status != GSL_SUCCESS) {
printf("Error: %s\n", gsl_strerror(status));
throw std::logic_error(gsl_strerror(status));
}
}
double getT() {
return t;
}
void setY(double* y) {
y = y;
}
private:
const gsl_odeiv2_step_type* T;
gsl_odeiv2_step* s;
gsl_odeiv2_control* c;
gsl_odeiv2_evolve* e;
gsl_odeiv2_system sys;
const size_t size;
double t;
double t1;
double h;
double* y;
double tPrev;
double* yPrev;
};
and then
int main() {
double state[] = { 1.0, 0.0, 0.0, 0.796975, 0.11637, 0.0185312};
const size_t size = 6;
DynSys system(size, 0.0, 40.0, 1e-3, state, func, jac);
system.step();
printf("t: %.5f\n", system.getT());
system.step();
printf("t: %.5f\n", system.getT());
return 0;
}
edit: Here's a link to the GSL functions GSL ODE

Related

cannot convert argument 3 from 'const char[7] to char*' in vs express 2017 errors E0289 and C2664

I'm using Visual Studio Express 2017 to work with OpenGL. My teacher provided the class with this code that worked on the lab computers which had the 2012 version installed, but on my PC it is not working. It keeps giving me 2 errors:
no instance of constructor canvas::canvas matches the argument list. E0289
This error is on the line Canvas cvs(640, 480, "my prog");
Canvas::canvas(canvas&&)
cannot convert argument 3 from 'const char[7] to char*'
C2664
This error is on the line if (n < 3)
Sorry, it's my first time using this site, so I pasted the entire code. It would be great if anyone could help me with this. I'm not really good with programming.
#include "stdafx.h"
#include<Windows.h>
#include<glut.h>
#include<gl/GLU.h>
#include <gl/GL.H>
#include<math.h>
#include<fstream>
void myInit(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0);
glColor3ub(1.0, 1.0, 1.0);
glPointSize(100.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 640.0, 0.0, 480.0);
}
class Point2 //single point w/ floating point coordinates
{
public:
Point2() { x = y = 0.0f; }
Point2(float xx, float yy) { x = xx; y = yy; }
void set(float xx, float yy) { x = xx; y = yy; }
float getX() { return x; }
float getY() { return y; }
void draw(void)
{
glBegin(GL_POINTS); //draw this point
glVertex2f((GLfloat)x, (GLfloat)y);
glEnd();
}
private:
float x, y;
};
class IntRect //aligned rectangle with integer coordinates, used for viewport
{
public:
IntRect() { l = 0; r = 100; b = 0; t = 100; }
IntRect(int left, int right, int bottom, int top)
{
l = left; r = right; b = bottom; t = top;
}
void set(int left, int right, int bottom, int top)
{
l = left; r = right; b = bottom; t = top;
}
void draw(void); //draw this rectangle using OpenGL
int getL(void)
{
return l;
}
int getR(void)
{
return r;
}
int getT(void)
{
return t;
}
int getB(void)
{
return b;
}
private:
int l, r, b, t;
};
class RealRect //simlar to IntRect but w/ floating points & used for world window
{
public:
RealRect() { l = 0; r = 100; b = 0; t = 100; }
RealRect(float left, float right, float bottom, float top)
{
l = left; r = right; b = bottom; t = top;
}
void set(float left, float right, float bottom, float top)
{
l = left; r = right; b = bottom; t = top;
}
float getL(void)
{
return l;
}
float getR(void)
{
return r;
}
float getT(void)
{
return t;
}
float getB(void)
{
return b;
}
void draw(void); //draw this rectangle using OpenGL
private:
float l, r, b, t;
};
//<<End Support Classes>>>
class Canvas
{
public:
Canvas(int width, int height, char* windowTitle); //constructor
void setWindow(float l, float r, float b, float t);
void setViewport(int l, int r, int b, int t);
IntRect getViewport(void); //divulge the viewport data
RealRect getWindow(void); // divulge the window data
float getWindowAspectRatio(void);
void clearScreen();
void setBackgroundColor(float r, float g, float b);
void setColor(float r, float g, float b);
void lineTo(float x, float y);
void lineTo(Point2 p);
void moveTo(float x, float y);
void moveTo(Point2 p);
void moveRel(float dx, float dy);
void turnTo(float angle);
void turn(float angle);
void forward(float dist, int isVisible);
Point2 Tween(Point2 A, Point2 B, float t);
void drawTween(Point2 A[], Point2 B[], int N, float t);
private:
Point2 CP; //current position in the world
float CD; //current direction in the world
IntRect viewport; //the current window
RealRect window; //the current viewport
};
//<<moveTo>>
//changes current point
void Canvas::moveTo(float x, float y)
{
CP.set(x, y);
}
//<<lineTo>>
//draws a line from current point to new point
void Canvas::lineTo(float x, float y)
{
glBegin(GL_LINES);
glVertex2f((GLfloat)CP.getX(), (GLfloat)CP.getY());
glVertex2f((GLfloat)x, (GLfloat)y); //draw the line
glEnd();
CP.set(x, y); //update current point to new point
glFlush();
}
//<<setWindow>>
void Canvas::setWindow(float l, float r, float b, float t)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D((GLdouble)l, (GLdouble)r, (GLdouble)b, (GLdouble)t);
window.set(l, r, b, t);
}
//<<setViewport>>
void Canvas::setViewport(int l, int r, int b, int t)
{
glViewport(l, b, r - l, t - b);
viewport.set(l, r, b, t);
}
IntRect Canvas::getViewport(void)
{
return viewport;
}
RealRect Canvas::getWindow(void)
{
return window;
}
void Canvas::clearScreen(void)
{
glClear(GL_COLOR_BUFFER_BIT);
}
void Canvas::setBackgroundColor(float r, float g, float b)
{
glClearColor(r, g, b, 0.0); //4th variable level of transparency, may need to change
}
void Canvas::setColor(float r, float g, float b)
{
glColor3f(r, g, b);
}
void Canvas::lineTo(Point2 p)
{
glBegin(GL_LINES);
glVertex2f((GLfloat)CP.getX(), (GLfloat)CP.getY());
glVertex2f((GLfloat)p.getX(), (GLfloat)p.getY());
glEnd();
CP.set(p.getX(), p.getY());
glFlush();
}
Canvas::Canvas(int width, int height, char* windowTitle)
{
char* argv[1]; //dummy argument list for glutinit()
char dummyString[8];
argv[0] = dummyString; //hook up the pointer
int argc = 1;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(width, height);
glutInitWindowPosition(20, 20);
glutCreateWindow("FourCircle");
setWindow(0, (float)width, 0, (float)height); // default world window
setViewport(0, width, 0, height); //default viewport
CP.set(0.0f, 0.0f); //initialize the cp to (0,0)
}
void Canvas::moveTo(Point2 p) //moves current point CP to point p object
{
float x1, y1;
x1 = p.getX();
y1 = p.getY();
CP.set(x1, y1);
}
float Canvas::getWindowAspectRatio(void) //calculates aspect ratio of world window
{
float width, height, aspectRatio;
width = window.getR() - window.getL();
height = window.getT() - window.getB();
aspectRatio = width / height;
return aspectRatio;
}
void Canvas::moveRel(float dx, float dy)
{
CP.set(CP.getX() + dx, CP.getY() + dy);
}
void Canvas::turnTo(float angle)
{
CD = angle;
}
void Canvas::turn(float angle)
{
CD += angle;
}
void Canvas::forward(float dist, int isVisible)
{
const float RadPerDeg = 0.017453393; //radians per degree
float x = CP.getX() + dist * cos(RadPerDeg * CD);
float y = CP.getY() + dist * sin(RadPerDeg * CD);
if (isVisible)
lineTo(x, y);
else
moveTo(x, y);
}
Point2 Canvas::Tween(Point2 A, Point2 B, float t)
{
Point2 P;
P.set(A.getX() + (B.getX() - A.getX())*t, A.getY() + (B.getY() - A.getY())*t);
return P;
}
class point {
public:
int x, y;
};
void Canvas::drawTween(Point2 A[], Point2 B[], int N, float t)
{
for (int i = 0; i < N; i++)
{
Point2 P;
P = Tween(A[i], B[i], t);
if (i == 0) moveTo(P.getX(), P.getY());
else lineTo(P.getX(), P.getY());
}
}
Canvas cvs(640, 480, "my prog");
void ngon(int n, float x, float y, float radius, float rot)
{
if (n < 3)
return;
double angle = rot * 3.141592 / 180;
double angleinc = 2 * 3.141592 / n;
cvs.moveTo(radius*cos(angle) + x, radius*sin(angle) + y);
for (int i = 0; i < n; i++)
{
angle += angleinc;
cvs.lineTo(radius*cos(angle) + x, radius*sin(angle) + y);
}
glFlush();
}
void display(void)
{
glColor3ub(255, 60, 60);
ngon(100, 300, 320, 60, 90);//top
ngon(100, 300, 200, 60, 90);//bottom
ngon(100, 240, 260, 60, 90);//left
ngon(100, 360, 260, 60, 90);//right
ngon(100, 260, 300, 60, 90);//top left
ngon(100, 340, 300, 60, 90);//top right
ngon(100, 260, 220, 60, 90);//bottom left
ngon(100, 340, 220, 60, 90);//bottom right
glFlush();
}
void main(void)
{
glutDisplayFunc(display);
glutMainLoop();
}
The code is not valid since C++11 and makes use of a deprecated conversion before that. A string literal is not convertible to char*, only to const char*.
So the constructor should read
Canvas(int width, int height, const char* windowTitle); //constructor
^^^^^
Depending on the settings, Visual Studio will accept the wrong version anyway, even in newer standard version modes, but that is not standard-conform.
Interestingly the constructor parameter seems to be unused in the definition of the constructor, so maybe just remove it completely.
The constructor also has another issue: glutInit is supposed to be passed argc and argv from main's parameters directly. The shown code passes a pointer to an uninitialized array instead. Depending on what glutInit does with this, it is likely to cause undefined behavior for reading uninitialized values of dummyString.
void main(void) is also not legal standard C++. The return type of main should always be int. Using void as single parameter for an empty parameter list is allowed, but unconventional, in C++. It comes from C, where it has a different meaning from an empty parameter list. In C++ one would usually just write () instead of (void).

c++ return two arrays from the function

I find a solution to the equation using the bisection method.
And I need to find the value of a and b on some iterations. Therefore, I made two arrays for these points, respectively.
in order to "pull out" the number of iterations from the function, I had no problems. They are displayed on the screen. But how do I "pull out" these two arrays?Please tell me how to do it. Thank you in advance!
double f1(double x){
return x*x-5*sin(x);
}
double f2(double x){
return exp(x)-pow(10,x);
}
double f3(double x){
return sin(x)-x+0.15;
}
double f4(double x){
return x-pow(9+x,0.5)+x*x-4;
}
double dihotom (double a , double b , double e , double(*fp)(double),int &iter,double &points_a[],double &points_b[]){
double c , fc , fa = fp(a);
iter=(log10((b-a)/e))/log10(2);
int step = iter/3;
int step_current = step;
int it=0;
int k=0;
do{
c=(a+b)/2;
fc=fp(c);
if (fa*fc<=0) b = c ; else a = c;
it++;
if(it==step_current){
points_a[k]=a;
points_b[k]=b;
k++;
step_current=step_current+step;
}
fa=fp(a);
printf ("it %d: a = %lf,b = %lf\n",iter,a,b);
}while (fabs(a-b)>=e);
return c;
}
int main(int argc, char *argv[]) {
int int_s=0;
double points_a[3];
double points_b[3];
double k3= dihotom (0.5,1,0.0001,f3,int_s,points_a[3],points_b[3]);
printf("For F3 - root = %lf, F3(%.2lf)=%lf ;iter =%d\n", k3, k3 ,f3(k3),int_s);
int i=0;
for(i=0;i<3;i++){
printf("step : %d , a: %lf, b: %lf ", i,points_a[i],points_b[i]);
}
return 0;
}
In your case, you should take the arrays by reference:
double dihotom(double a, double b, double e, double (*fp)(double), int &iter,
double (&points_a)[3], double (&points_b)[3]) {
// ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^
You could also let the arrays decay into pointers:
double dihotom(double a, double b, double e, double (*fp)(double), int &iter,
double points_a[], double points_b[]) {
or
double dihotom(double a, double b, double e, double (*fp)(double), int &iter,
double* points_a, double* points_b) {
But by taking them by reference, you make sure that you only accept arrays of the correct size.
In either case, the call to the function will simply be:
double k3 = dihotom(0.5, 1, 0.0001, f3, int_s, points_a, points_b);
Demo
If you want to return two arrays from a function then make a struct with two vectors. Something like this. The way you are doing it is harder to maintain, who will allocate the arrays and delete them for example?
// todo for you : create better names then points_a and points_b
struct my_result_t
{
std::vector<double> points_a;
std::vector<double> points_b;
};
my_result_t function();
{
my_result_t result;
result.points_a.push_back(1.0);
result.points_b.push_back(2.0);
return result;
}
int main()
{
auto result = function();
std::cout << result.points_a[0];
}

Unable to read memory for object array deletion

So I am testing out some object arrays in C++, and I am trying to delete these objects afterwards, as I am supposed to.
But here's the problem: the deleteInputPattern variable works fine, so I am able to fully delete "inputs" within the CSVFile header class, but its equivalent in the main file, "inputArray", triggers a breakpoint.
What is the problem here? Am I trying to delete non-existent memory? Do any of the pointers need
Code wall below:
InputTest.h:
#pragma once
class InputTest
{
private:
float r;
float g;
float b;
float t;
public:
InputTest();
~InputTest();
InputTest(float r, float g, float b, float t);
void setR(float newT);
float getR();
void setG(float newT);
float getG();
void setB(float newT);
float getB();
void setT(float newT);
float getT();
void print(int count);
};
InputTest.cpp:
#include "InputTest.h"
#include <stdio.h>
InputTest::InputTest()
{
printf("Input constructor\n");
}
InputTest::~InputTest()
{
printf("Input destructor\n");
}
InputTest::InputTest(float r, float g, float b, float t)
{
this->r = r;
this->g = g;
this->b = b;
this->t = t;
}
void InputTest::setR(float newT)
{
r = newT;
}
float InputTest::getR()
{
return r;
}
void InputTest::setG(float newT)
{
g = newT;
}
float InputTest::getG()
{
return g;
}
void InputTest::setB(float newT)
{
b = newT;
}
float InputTest::getB()
{
return b;
}
void InputTest::setT(float newT)
{
t = newT;
}
float InputTest::getT()
{
return t;
}
void InputTest::print(int count)
{
printf("R: %.2f\n", r);
printf("G: %.2f\n", g);
printf("B: %.2f\n", b);
printf("T: %.2f\n", t);
}
Copy.h:
#pragma once
class InputTest;
class Copy
{
private:
int patternCount;
InputTest** inputs;
public:
Copy();
~Copy();
InputTest* getInputPattern(int index);
void addInputPattern(InputTest* in);
void deleteInputPattern();
};
Copy.cpp:
#include "Copy.h"
#include "InputTest.h"
#include <string.h>
#include <stdio.h>
Copy::Copy()
{
printf("CSV File constructor\n");
inputs = NULL;
patternCount = 0;
inputs = new InputTest*[3];
int i;
for (i = 0; i < 3; i++)
{
inputs[i] = new InputTest();
}
}
Copy::~Copy()
{
printf("CSV File destructor\n");
}
InputTest * Copy::getInputPattern(int index)
{
printf("input gotten: %d\n", index);
return inputs[index];
}
void Copy::addInputPattern(InputTest * in)
{
inputs[patternCount] = in;
patternCount++;
printf("input added: %d\n", patternCount);
}
void Copy::deleteInputPattern()
{
int i;
for (i = 0; i < patternCount; i++)
{
delete inputs[i];
}
delete inputs;
inputs = NULL;
}
main.cpp:
#include "Copy.h"
#include "InputTest.h"
#include <string.h>
#include <stdio.h>
int main(int argv, char** argc)
{
bool testResult = false;
Copy *test = NULL;
test = new Copy();
InputTest **inputArray;
inputArray = new InputTest*[3];
int count;
for (count = 0; count < 3; count++)
{
inputArray[count] = new InputTest();
inputArray[count]->setR(0.2f);
inputArray[count]->setG(0.6f);
inputArray[count]->setB(0.8f);
inputArray[count]->setT(0.5f);
test->addInputPattern(inputArray[count]);
inputArray[count] = test->getInputPattern(count);
printf("next\n");
}
for (count = 0; count < 3; count++)
{
printf("round %d\n", count);
printf("R: %f\n", inputArray[count]->getR());
printf("G: %f\n", inputArray[count]->getG());
printf("B: %f\n", inputArray[count]->getB());
printf("T: %f\n", inputArray[count]->getT());
}
test->deleteInputPattern();
for (count = 0; count < 3; count++)
{
delete inputArray[count];
}
delete inputArray;
delete test;
inputArray = NULL;
test = NULL;
return testResult;
}
These seem to be the problematic line:
test->deleteInputPattern();
for (count = 0; count < 3; count++)
{
delete inputArray[count];
}
Since you have already deleted using test->deleteInputPattern(), that memory is freed. Now you are deleting the same objects (to which you are still holding a reference via inputArray) explicitly in main using delete inputArray. But that memory is already deleted in deleteInputPattern and hence you should be getting a memory access error.
You need to free any allocated memory only once. There is no need to do it again in main(). Either call deleteInputPattern or call delete explicitly in main, but not both. I can recommend 2 best practices:
Use smart pointers
The allocating module should delete the memory (this may not be applicable in many situations though such as factories)

Why does my vector of pointers keep on resulting in a EXC_BAD_ACCESS?

I am attempting to create a graphical representation of finite automata using xcode, and as such I have created classes for states and transitions. In order to make moving objects easy, I have included a collection of pointers of transitions going in and out of the state. Compiling is fines, but when I try to append to the vector, it produces the following error. EXC_BAD_ACCESS(code=1, address=0x3f35)
Following the error takes me to the std library, and shows the error being in this line.
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
void
vector<_Tp, _Allocator>::push_back(const_reference __x)
{
if (this->__end_ != this->__end_cap())
{
__annotate_increase(1);
__alloc_traits::construct(this->__alloc(),
_VSTD::__to_raw_pointer(this->__end_), __x);
++this->__end_;
}
else
__push_back_slow_path(__x);
}
Here is a simplified version of my State class, my Transition class is declared before and is then defined afterwards.
class State
{
int id;
std::vector<Transition *> links_in;
std::vector<Transition *> links_out;
float x;
float y;
int r = radius; //x, y are centre coordinates of the circle representing the state, while r is the radius
bool is_active = false;
bool is_end = false;
bool is_shown = true;
bool is_moving;
public:
// Get Functions go here
// Set Functions go here
//Add functions
void add_in_trans(Transition * t){
links_in.push_back(t);
}
void add_out_trans(Transition * t){
links_out.push_back(t);
}
//Delete Functions
void remove_in_trans(){
links_in.pop_back();
}
void remove_out_trans(){
links_out.pop_back();
}
void draw_state();
State(int ix, int iy);
State(){}
}
If you have any suggestions for a better way of doing this, I am more then happy to hear them. I have spent all day trying to sort this out, to no avail.
Thanks in advance.
UPDATE:
I attempted to use integers and vectors as a temporary fix, but I came up with the same problem, so I assume that the problem isn't the pointers but the way I'm using vectors.
This is the code
#include <vector>
class Transition;
class State
{
int id;
std::vector<int> links_in;
std::vector<int> links_out;
float x;
float y;
int r = radius; //x, y are centre coordinates of the circle representing the state, while r is the radius
bool is_active = false;
bool is_end = false;
bool is_shown = true;
bool is_moving;
public:
// Get Functions
int get_x(){
return x;
}
int get_y(){
return y;
}
int get_id(){
return id;
}
bool is_it_active(){
return is_active;
}
bool is_it_moving(){
return is_moving;
}
bool is_in(int ix, int iy){ //Function to tell if pair of coordinates are in the circle, used to select.
std::cerr << ix-x << " " << iy-y << " " << r*r << std::endl;
if ((ix-x)*(ix-x) + (iy-y)*(iy-y) < r*r)
return true;
else
return false;
}
// Set Functions
void set_active(bool s){
is_active = s;
}
void set_moving(bool s){
is_moving = s;
}
void end_switch(){
is_end = !is_end;
}
void set_start(){
g_start_state = id;
}
void set_x(int ix){
x = ix;
}
void set_y(int iy){
y = iy;
}
//Add functions
void add_in_trans(int t){
links_in.push_back(t);
}
void add_out_trans(int t){
links_out.push_back(t);
}
//Delete Functions
void remove_in_trans(){
links_in.pop_back();
}
void remove_out_trans(){
links_out.pop_back();
}
void draw_state();
State(int ix, int iy);
State(){}
};
State::State(int ix, int iy){
id = g_state_num;
if (g_start_state == 0)
g_start_state = id;
x = ix;
y = iy;
}
void State::draw_state(){
if (is_shown){
if (is_moving)
glTranslatef(g_cursor_x, g_cursor_y, 0.0);
else
glTranslatef(x, y, 0.0);
fill_colour();
if (is_active)
active_fill_colour();
glBegin(GL_POLYGON);
for (size_t i=0; i<24; i++){
float n[2] = {static_cast<float>(r * cos(i*6)), static_cast<float>(r * sin(i*6))};
glVertex2fv(n);
}
glEnd();
line_colour();
glBegin(GL_LINES);
for (size_t i=0; i<24; i++){
float n[2] = {static_cast<float>(r * cos(i*6)), static_cast<float>(r * sin(i*6))};
glVertex2fv(n);
}
glEnd();
if(is_end){
glPushMatrix();
glScalef(0.9, 0.9, 0.9);
for (size_t i=0; i<24; i++){
float n[2] = {static_cast<float>(r * cos(i*6)), static_cast<float>(r * sin(i*6))};
glVertex2fv(n);
}
glPopMatrix();
}
text_colour();
std::string s = std::to_string(id);
for (int i=0; i<s.length(); i++){
glPushMatrix();
glTranslatef(-radius/2 + i*kerning, -radius/2, 0.0);
glScalef(0.3, 0.3, 1.0);
glutStrokeCharacter(GLUT_STROKE_ROMAN, s[i]);
glPopMatrix();
}
}
}
class Character{
int id;
char c;
public:
int get_id(){
return id;
}
char get_char(){
return c;
}
void set_char(char ic){
c = ic;
}
Character(char ic);
Character(){};
};
Character::Character(char ic){
id = g_character_num;
g_character_num++;
c = ic;
}
class Transition{
int ident;
State * from_state;
State * to_state;
float from[2];
float to[2];
Character c;
public:
void set_from(float x, float y){
from[0] = x;
from[1] = y;
}
void set_to(float x, float y){
to[0] = x;
to[1] = y;
}
void set_char(Character ic){
c = ic;
}
int get_id(){
return ident;
}
void draw_trans();
void set_trans(State * ifrom, State * ito, Character ic){
from_state = ifrom;
to_state = ito;
from[0] = ifrom->get_x();
from[1] = ifrom->get_y();
to[0] = ito->get_x();
to[1] = ito->get_y();
c = ic;
}
Transition(){};
Transition(State ifrom, State ito, Character ic){
from_state = &ifrom;
to_state = &ito;
from[0] = ifrom.get_x();
from[1] = ifrom.get_y();
to[0] = ito.get_x();
to[1] = ito.get_y();
c = ic;
}
};
void Transition::draw_trans(){
line_colour();
glBegin(GL_LINES);
glVertex2fv(from);
glVertex2fv(to);
glEnd();
float grad = (from[0] - to[0]) /(from[1] - to[1]); //(By finding the gradient of the slope, we can fin good place to show it's information, it's character.
if (grad < -1 || grad > 1){
glPushMatrix();
glTranslatef(from[0] - to[0] - 20, from[1] - to[1], 1.0);
}
else{
glPushMatrix();
glTranslatef(from[0] - to[0], from[1] - to[1] + 20, 1.0);
}
glutStrokeCharacter(GLUT_STROKE_ROMAN, (c.get_char()));
glPopMatrix();
}

why is this an invalid conversion when the argument I am giving is an int

This is my program:
#include <iostream>
using namespace std;
class Point
{
private: int x, y;
public:
Point(int f = 0, int g = 0)
{
x = f;
y = g;
}
int getX() const
{
return x;
}
int getY() const
{
return y;
}
void setX(const int new_x)
{
x = new_x;
}
void setY(const int new_y)
{
y = new_y;
}
};
class PointArray
{
private:
Point * loc;
int len;
public:
PointArray()
{
len = 0;
loc = new Point[0];
}
PointArray(const Point * points, const int size)
{
len = size;
loc = new Point[len];
for(int f = 0; f < len; f++)
loc[f] = points[f];
}
PointArray(const PointArray& pv)
{
len = pv.len;
loc = new Point[len];
for(int f = 0; f < len; f++)
loc[f] = pv.loc[f];
}
~PointArray()
{
delete[] loc;
}
void resize(int n)
{
Point *loc1 = new Point[n];
for(int f = 0; f < len && f < n; f++)
loc1[f] = loc[f];
len = n;
delete[] loc;
loc = loc1;
}
void pushBack(const Point &p)
{
resize(len+1);
loc[len-1] = p;
}
void insert(const int pos, const Point &p)
{
resize(len+1);
for(int f = len-1; f > pos; f--)
loc[f] = loc[f-1];
loc[pos] = p;
}
void remove(const int pos)
{
for(int f = pos; f < len-1; f++)
loc[f] = loc[f+1];
resize(len-1);
}
const int getSize() const
{
return len;
}
void clear()
{
resize(0);
}
Point * get(const int pos)
{
if (pos >= len)
return NULL;
else
{
Point * x = new Point();
*x = loc[pos];
return x;
}
}
const Point * get(const int pos) const
{
if (pos >= len)
return NULL;
else
{
Point * x = new Point();
*x = loc[pos];
return x;
}
}
};
class Polygon
{
protected:
PointArray * loci;
int sides;
static int N;
public:
Polygon(Point * loc, int len)
{
loci = new PointArray(loc, len);
sides = len;
N++;
}
Polygon(const PointArray& pv)
{
loci = new PointArray(pv);
sides = pv.getSize();
N++;
}
Polygon(const Polygon& pv)
{
loci = new PointArray(*pv.loci);
sides = pv.sides;
N++;
}
~Polygon()
{
delete loci;
N--;
}
virtual double area() = 0;
static int getNumPolygons()
{
return N;
}
int getNumSides()
{
return sides;
}
const PointArray * getPoints()
{
return loci;
}
};
class Rectangle : public Polygon
{
private:
typedef Polygon super;
void makeRectangle(const Point e, const Point r)
{
Point * loci = new Point[4];
loci[0] = e;
loci[2] = r;
loci[1] = new Point(e.getX(), r.getY());
loci[3] = new Point(r.getX(), e.getY());
}
void makeRectangle (const int x1, const int x2, const int y1, const int y2)
{
Point * loci = new Point[4];
loci[0] = new Point(x1, y1);
loci[1] = new Point(x2, y1);
loci[2] = new Point(x2, y2);
loci[3] = new Point(x1, y2);
}
};
The compiler is giving me these errors in the two overloaded makeRectangle() when they call the Point(int, int) constructor, saying:
geometry.cpp: In member function 'void Rectangle::makeRectangle(Point, Point)':
geometry.cpp:170:45: error: invalid conversion from 'Point*' to 'int' [-fpermissive]
geometry.cpp:8:4: error: initializing argument 1 of 'Point::Point(int, int)' [-fpermissive]
geometry.cpp:171:45: error: invalid conversion from 'Point*' to 'int' [-fpermissive]
geometry.cpp:8:4: error: initializing argument 1 of 'Point::Point(int, int)' [-fpermissive]
geometry.cpp: In member function 'void Rectangle::makeRectangle(int, int, int, int)':
geometry.cpp:176:33: error: invalid conversion from 'Point*' to 'int' [-fpermissive]
geometry.cpp:8:4: error: initializing argument 1 of 'Point::Point(int, int)' [-fpermissive]
geometry.cpp:177:33: error: invalid conversion from 'Point*' to 'int' [-fpermissive]
geometry.cpp:8:4: error: initializing argument 1 of 'Point::Point(int, int)' [-fpermissive]
geometry.cpp:178:33: error: invalid conversion from 'Point*' to 'int' [-fpermissive]
geometry.cpp:8:4: error: initializing argument 1 of 'Point::Point(int, int)' [-fpermissive]
geometry.cpp:179:33: error: invalid conversion from 'Point*' to 'int' [-fpermissive]
geometry.cpp:8:4: error: initializing argument 1 of 'Point::Point(int, int)' [-fpermissive]
Because x1, x2, y1, and y2 are integers and therefore should be compatible with the Point(int, int) constructor, I do not understand why it is giving me the error: "invalid conversion from 'Point*' to 'int'".
Getters and setters
Having getters and setters for the sake of having them is never a good idea. Therefore your code for Point can be reduced to:
struct Point {
int x;
int y;
};
Which not only is easier and faster to read, but is just as constant correct as your solution was.
The array
Your PointArray class is less than reusable. You can use standard containers instead. Your PointArray class can be reduced to:
using PointArray = std::vector<Point>;
The Polygon base class
The Polygon class can also be improved. First of all you don't need loci to be dynamically allocated. You should use:
class Polygon {
protected:
PointArray loci;
int sides;
static int N;
Now, for the constructor you could use the following instead of the C-style array that you are expecting from the first constructor:
public:
Polygon(const PointArray& loc) {
loci = loc
sides = loc.size();
N++;
}
As you can see there's no need for the len argument. You could also use an std::initializer_list to allow expressions like:
Polygon x { Point(...), Point(...), Point(...), ... };
And here's how:
Polygon(const std::initializer_list<Point> list)
: loci(list)
, sides(list.size())
{ N++; }
And after your smart edit you can get rid of the custom copy constructor and destructor, effectively following the Rule of Zero.
The rest is pretty much the same:
virtual double area() = 0;
static int getNumPolygons() { return N; }
int getNumSides() { return sides; }
except for getPoints. I'd suggest two different overloads: const and non-const:
PointArray& getPoints() { return loci; }
const PointArray& getPoints() const { return loci; }
};
The Rectangle class
And finally your rectangle class can, of course, be improved:
class Rectangle : public Polygon {
private:
void makeRectangle(const Point& e, const Point& r) {
loci.push_back(e);
loci.push_back(r);
loci.emplace_back(e.x, r.y);
loci.emplace_back(r.x, e.y);
}
void makeRectangle (const int x1, const int x2, const int y1, const int y2) {
loci.emplace_back(x1, y1);
loci.emplace_back(x2, y1);
loci.emplace_back(x2, y2);
loci.emplace_back(x1, y2);
}
};
Conclusion
After this simple refactoring, all your errors should be gone and your code should be much shorter and readable.