2
votes

I am trying to create a parent class "Shape" with child classes "Circle", "Triangle", "Rectangle". The parent class holds the x pos, y pos, and fill color or all the "shapes" and then each child class holds info specific to that shape. Would anyone mind looking over my code and see why im getting the error "Shapes does not have a member 'setRadius'" when trying to set the radius in the array of objects...

P.S. right now I only have the child class "Circle" until i get it working. Then I will add the other two classes.

Also, if anyone sees any other errors in my code, I would appreciate them being pointed out.

Thanks in advance

#include <allegro.h>
#include <cstdlib>

using namespace std;

#define scrX 640
#define scrY 400
#define WHITE makecol(255,255,255)
#define GRAY makecol(60,60,60)
#define BLUE makecol(17,30,214)

int random(int low, int high);

const int numCircles = random(1,50);

class Shape{
    public:
        Shape(){x = scrX / 2; y = scrY / 2; fill = WHITE;}
    protected:
        int x, y, fill;    
};
class Circle : public Shape{
    public:
        Circle(){radius = 0;}
        Circle(int r){radius = r;}
        void setRadius(int r){radius = r;}
    protected:
        int radius;
};
int main() 
{   
    // Program Initialization
    allegro_init();
    install_keyboard();
    set_color_depth(32);
    set_gfx_mode(GFX_AUTODETECT_WINDOWED, scrX, scrY, 0, 0);

    // Create and clear the buffer for initial use
    BITMAP *buffer = create_bitmap(scrX, scrY);
    clear_to_color(buffer, GRAY);

    // Set title and create label text in window
    set_window_title("Bouncing Balls Ver 1.0");
    textout_ex(buffer, font, "Bouncing Balls Ver 1.0", 10, 20, WHITE, GRAY);

    // Draw a background box
    rectfill(buffer, 50, 50, scrX-50, scrY-50, BLUE);

    // Create circles
    Shape **GCir;
    GCir = new Shape *[numCircles];
    for(int i=0;i<numCircles;i++){
        GCir[i] = new Circle;
        GCir[i]->setRadius(random(1,25)); // THIS IS THE ERROR        
    }

    while(!key[KEY_ESC]){
    blit(buffer, screen, 0, 0, 0, 0, scrX, scrY);
    }

    destroy_bitmap(buffer);

    return 0;
}
END_OF_MAIN();
int random(int low, int high)
{
    return rand() % (high - low) + low;
}
3

3 Answers

2
votes

The type of GCir[i] is Shape* and the Shape class doesn't have a setRadius method, Circle does. So either call setRadius on the Circle object before assign it to GCir[i] or just construct the Circle with the proper radius: GCir[i] = new Circle(random(1,25));

1
votes

hammer fix :

GCir[i]->setRadius(random(1,25));

should be changed to

((Circle*)GCir[i])->setRadius(random(1,25));

Deeper problems:

you need virtual destructor on BaseClass

a better way to do it is to take the radius in the Circle class constructor. then either use Shape::draw() as a virtual function to specify shape drawing or implement Shape::getType() and use a switch case to determine drawing logic after proper casting.

0
votes

Compiler said it. You have an array of Shapes on which you try to call setRadius which is only defined for Circles. You can only call shape methods without casting Shape poonter to circle.