I have a virtual function printShape() in class Shape and classes Rect,Line and Circle, which override it, then I create an array of Shapes (Shape**) and which holds derived objects, but when I traverse the array every derived object inside the array calls the function printShape() from shape instead the one it has overriden.Here are my Shape and Rectangle classes and the TextManager class where I create and fill the Shape array. Pay no attention to how poorly some other parts of the code are written.
Shape.h:
#ifndef SHAPE
#define SHAPE
class Shape
{
public:
Shape();
virtual ~Shape();
virtual void printShape()const;
virtual bool isWithin(const Shape*) const;
virtual void translate(double,double);
public:
void setFill(const char*);
const char* getFill() const;
private:
char fill[10];
};
#endif
Rect.h:
#ifndef RECT
#define RECT
#include "Shape.h"
class Rect :public Shape
{
public:
Rect();
Rect(double, double, unsigned int, unsigned int);
virtual ~Rect();
public:
virtual bool isWithin(char* name, double x, double y, double ) const;
virtual bool isWithin(char* name, double x, double y, unsigned int w, unsigned int h) const;
virtual void translate(double,double);
void printShape()const;
public:
void setX(double);
void setY(double);
void setWidth(unsigned int);
void setHeight(unsigned int);
double getX();
double getY();
unsigned int getWidth();
unsigned int getHeight();
private:
double x, y;
unsigned int width, height;
};
#endif
Rect.cpp:
#include "Rect.h"
#include <iostream>
void Rect::setX(double x)
{
this->x = x;
}
void Rect::setY(double y)
{
this->y = y;
}
void Rect::setWidth(unsigned int w)
{
this->width = w;
}
void Rect::setHeight(unsigned int h)
{
this->height = h;
}
double Rect::getX()
{
return this->x;
}
double Rect::getY()
{
return this->y;
}
unsigned int Rect::getWidth()
{
return this->width;
}
unsigned int Rect::getHeight()
{
return this->height;
}
Rect::Rect()
{
this->x = 0;
this->y = 0;
this->width = 0;
this->height = 0;
}
Rect::Rect(double X,double Y, unsigned int W, unsigned int H)
{
setX(X);
setY(Y);
setWidth(W);
setHeight(H);
}
Rect::~Rect()
{
}
void Rect::printShape()const
{
std::cout << "rectangle ";
std::cout
<< this->x << " "
<< this->y << " "
<< this->width << " "
<< this->height << " ";
std::cout<<getFill();
}
bool Rect::isWithin(char* name, double x, double y, unsigned int w, unsigned int h) const
{
return !((this->x < x) || (this->y < y) || (this->width + this->x >(w + x)) || (this->height + this->y >(h + y)));
}
bool Rect::isWithin(char* name, double x, double y, double rad) const{
return ((this->x < x + rad) || this->x > x - rad) && (this->y < y + rad) || this->y > y - rad &&
(this->x+width < x + rad) || (this->x+width > x - rad) && (this->y < y + rad) || (this->y > y - rad) &&
(this->x + width < x + rad) || (this->x + width > x - rad) && (this->y+height < y + rad) || (this->y+height > y - rad) &&
(this->x < x + rad) || (this->x > x - rad) && (this->y + height < y + rad) || (this->y + height > y - rad);
}
void Rect::translate(double vertical, double horizontal)
{
x += horizontal;
y += vertical;
}
I have a class ManageText which reads the data from an svg file and fills the array with a function called readFile()
#ifndef MANAGETEXT
#define MANAGETEXT
#include "Shape.h"
#include "Rect.h"
class ManageText
{
public:
ManageText();
~ManageText();
public:
void readFile(const char*);
void writeFile(const char*);
public:
int findSvg(const char*);
void insertLine(const char* line, int row);
void removeLine(const char*, int row);
char* getLineFile(int);
void setLine(const char*, int);
void eraseShape(int);
void printShapes(const char* nameFile) const;
void translateShapes(double, double);
void createRect(double x, double y, unsigned int w, unsigned int h, const char* f, int row, const char*);
void createCircle(double x, double y, double r, const char* f, int row, const char*);
void createLine(double x1, double y1, double x2, double y2, int row, const char*);
public:
int getNumberLines();
void setNumberLines(char* nameFile);
int getSizeofFile(char* nameFile);
char* getNameFile();
char** getText();
int getShapesSize(const char* fileName) const;
private:
void clear();
int getLinesFromFile(const char*);
private:
char* nameFile;
char** text;
int numberLines;
Shape** shapes;
int shapesSize;
};
#endif
readFile() in ManageText.cpp:
void ManageText::readFile(const char* nameFile)
{
std::ifstream file;
file.open(nameFile, std::ios::in);
if (!file.is_open())
{
std::cout << "error";
return;
}
else
{
//read number of figures
int cntShapes = getShapesSize(nameFile);
shapes = new Shape*[cntShapes];
char shape[500000];
char toNum[15];
int tmp = 0;
while (!file.eof())
{
file >> shape;
if (strcmp(shape, "<rect") == 0)
{
Rect rect;
double x;
double y;
unsigned int w, h;
file >> toNum;
int nx = strlen(toNum);
for (int i = 3; i < nx; i++)
{
toNum[i - 3] = toNum[i];
}
x = atof(toNum);
rect.setX(x);
file >> toNum;
int ny = strlen(toNum);
for (int i = 3; i < ny; i++)
{
toNum[i - 3] = toNum[i];
}
y = atof(toNum);
rect.setY(y);
file >> toNum;
int nw = strlen(toNum);
for (int i = 7; i < nw; i++)
{
toNum[i - 7] = toNum[i];
}
w = atof(toNum);
rect.setWidth(w);
file >> toNum;
int nh = strlen(toNum);
for (int i = 8; i < nw; i++)
{
toNum[i - 8] = toNum[i];
}
h = atof(toNum);
rect.setHeight(h);
file >> toNum;
int nFill = strlen(toNum);
for (int i = 6; i < nFill; i++)
{
toNum[i - 6] = toNum[i];
}
toNum[nFill - 7] = '\0';
rect.setFill(toNum);
shapes[tmp] = ▭
tmp++;
}
else if (strcmp(shape, "<circle")==0)
{
Circle circle;
double x, y, r;
file >> toNum;
int nx = strlen(toNum);
for (int i = 4; i < nx; i++)
{
toNum[i - 4] = toNum[i];
}
x = atof(toNum);
circle.setX(x);
file >> toNum;
int ny = strlen(toNum);
for (int i = 4; i < ny; i++)
{
toNum[i - 4] = toNum[i];
}
y = atof(toNum);
circle.setY(y);
file >> toNum;
int nr = strlen(toNum);
for (int i = 3 ; i < nr; i++)
{
toNum[i - 3] = toNum[i];
}
r = atof(toNum);
circle.setRadius(r);
file >> toNum;
int nFill = strlen(toNum);
for (int i = 6; i < nFill; i++)
{
toNum[i - 6] = toNum[i];
}
toNum[nFill - 7] = '\0';
circle.setFill(toNum);
shapes[tmp] = &circle;
tmp++;
}
else if (strcmp(shape, "<line") == 0)
{
Line line;
double x1, y1, x2, y2;
file >> toNum;
int nx1 = strlen(toNum);
for (int i = 4; i < nx1; i++)
{
toNum[i - 4] = toNum[i];
}
x1 = atof(toNum);
line.setX1(x1);
file >> toNum;
int ny1 = strlen(toNum);
for (int i = 4; i < ny1; i++)
{
toNum[i - 4] = toNum[i];
}
y1 = atof(toNum);
line.setY1(y1);
file >> toNum;
int nx2 = strlen(toNum);
for (int i = 4; i < nx2; i++)
{
toNum[i - 4] = toNum[i];
}
x2 = atof(toNum);
line.setX2(x2);
file >> toNum;
int ny2 = strlen(toNum);
for (int i = 4; i < ny2; i++)
{
toNum[i - 4] = toNum[i];
}
y2 = atof(toNum);
line.setY2(y2);
file >> toNum;
int nFill = strlen(toNum);
for (int i = 6; i < nFill; i++)
{
toNum[i - 6] = toNum[i];
}
toNum[nFill - 7] = '\0';
line.setFill(toNum);
shapes[tmp] = &line;
tmp++;
}
}
}
}
So my question is why isn't every object from shapes array calling it's own printShapefunction, but the one from the Shape class?