Hello, I am terribly confused on how to start my most recent programming assignment. I am to use an abstract class (shapeO) to create a child class (animShapeO). The program is supposed to create rectangles and moving them (hypothetically as there are no graphics involved) across the screen and when they overlap with each other both disappear.

The shapeO class is defined for me.

#ifndef SHAPEO_H
#define SHAPEO_H
class shapeO {
public:

        shapeO() {};
        virtual ~shapeO() {};

    virtual  bool collidesWith( shapeO *) = 0 ;
    void getRect(double & X, double & Y, double & W, double & H)
        {  X = x; Y = y; W = width; H = height; }
    void setRect(double X , double Y, double W, double H)
        { x = X; y = Y; width=W; height=H;}
protected:
    double x,y, height, width;
};
#endif

and from this I am supposed create the child class animShapeO that has the member data
DIRECTIONVECTOR- which indicates the direction of the rectangle, two doubles x and y

If anyone could give me some insight on how to approach and structure this program it would help me out a lot as it has been a long time since i've worked with derived classes

thank you

Do you have to use the class word for word? Or can you change some return types and parameters.

I suppose some minor changes could be made but I know I am supposed to keep the collidesWith() function virtual.

What's the question? How to set use a virtual function? How to use a derived class? How to write a driver program? The mathematics behind collision detection? How to write the collison detection function? How to call it? Etc.

Who wrote the code you posted?

my professor wrote the code above. I need to write a derived class animShapeO.h and a driver program collision.cpp. What I want to know to get started is how to create the derived class, what it will need from the ShapeO.h class, how to include those, and what it will need that the ShapeO.h class does not have.

I could help more but I've come to the problem of not knowing how to use this.

bool collidesWith(shapeO *)

What does * mean? As in how do I get information ( getRect() ) from it?

my professor wrote the code above. I need to write a derived class animShapeO.h and a driver program collision.cpp. What I want to know to get started is how to create the derived class, what it will need from the ShapeO.h class, how to include those, and what it will need that the ShapeO.h class does not have.

If you haven't gone through the tutorials on derived classes already, do so. Your questions are vague enough to suggest that you have no idea what these concepts are. Write the traditional Animal class with derived classes Cat and Dog. You can have a virtual function called "Speak" in the Animal class and have the implementations be to display "meow" or "woof" accordingly. As far as class data members, both cats and dogs have names, but only dogs have licenses, so put those in the appropriate spots. Create a Dog and a Cat and make them speak in the Driver program. Something like that. ShapeO and animShape are much less intuitive, so they're harder to practice with. Animals, Dogs, Cats, Goldfish, etc. are easier to understand and it's more obvious what should inherit from what.

So after you practice a bit, have a nice simple program where you create two shapeO objects, give them some values, and write a nice easy collidesWith function that just returns false. Stick it all in one file so you don't have to deal with including anything till later.


I could help more but I've come to the problem of not knowing how to use this.

bool collidesWith(shapeO *)

It's a pure virtual function (no function body). collidesWith is implemented in the derived classes and takes a pointer to an object of type shapeO. The function declaration above doesn't specify a variable name for the parameter.

Edited 7 Years Ago by VernonDozier: n/a

Thanks to everyone for the help and advice I've been looking over examples of inheritance and derived classes. and this is what I have so far.

DRIVER PROGRAM

#include "animShapeO.h"
#include <iostream>
#include <vector>
using namespace std;

int X,Y,heigth,width;
int minDim = -5, maxDim = 5;

int numRects;
int main()
{

cout << "how many rectangles do you want to create?" << endl;
cin >> numRects;

vector<double> rect (numRects);

  for(int i=0;i<numRects;i++)
  {
    animShapeO* rect[i];
    rect[i].X = drand48() * 640;
    rect[i].Y = drand48() * 480;
    rect[i].width = minDim + drand48() * (maxDim - minDim);
    rect[i].heigth = minDim + drand48() * (maxDim - minDim);
    setRect(rect[i].X, rect[i].Y, rect[i].width, rect[i].heigth);
  }

    cout << "rectangles      " << "number of rectangles left" << endl;
  for(int i=0;i<numRects;i++)
  {
    cout << rect[i].X << "  " << rect[i].Y << "  " << rect[i].width << "  " << rect[i].heigth << endl;
  }
}

ANIMSHAPEO.H

#ifndef ANIMSHAPEO_H
#define ANIMSHAPEO_H
#include "shapeO.h"
#include <string>
#include <fstream>
using namespace std;

class animshapeO : public shapeO
{
        private:
        double directionX, directionY;

        public:
//      bool collidesWith()
//      {
//        if (rect.y > rect.y + rect.heigth)
//          return true;
//          else
//          return false;
//      }
//      update();
//      {

};
#endif

SHAPEO.H

#ifndef SHAPEO_H
#define SHAPEO_H
class shapeO {
public:

        shapeO() {};
        virtual ~shapeO() {};

    virtual  bool collidesWith( shapeO *) = 0 ;
    void getRect(double & X, double & Y, double & W, double & H)
        {  X = x; Y = y; W = width; H = height; }
    void setRect(double X , double Y, double W, double H)
        { x = X; y = Y; width=W; height=H;}
protected:
    double x,y, height, width;
};
#endif

On compiling I'm getting the error
animShapeO.cpp: In function 'int main()':
animShapeO.cpp:20: error: 'animShapeO' was not declared in this scope

and then some more errors about the X,Y,width, and height that i am passing to the functions but those could be because it is not recognizing the new class I am trying to add.

I know I haven't gotten very far but I am trying and I appreciate your guys help, thanks

Capitalization counts. Your class is called animshapeO. The line in your driver program refers to animShapeO, which is undefined. They must match.

Thanks vernor that seemd to take care of the a lot of the errors but now there this one seems to be the main problem. I must be using the pure virtual function wrong but am not sure how to correct it.

animShapeO.cpp:25: error: cannot allocate an object of abstract type 'animShapeO'

I copied the code above and it says that it works fine but I cannot use the drand48() function. I googled it and its for linux or something?

I don't seem to be having any problem using the function, I looked at the man page and here's a little bit of what it says


Standard C Library Functions drand48(3C)

NAME
drand48, erand48, lrand48, nrand48, mrand48, jrand48,
srand48, seed48, lcong48 - generate uniformly distributed
pseudo-random numbers

I don't seem to be having any problem using the function, I looked at the man page and here's a little bit of what it says


Standard C Library Functions drand48(3C)

NAME
drand48, erand48, lrand48, nrand48, mrand48, jrand48,
srand48, seed48, lcong48 - generate uniformly distributed
pseudo-random numbers

I think these are Linux-only functions. Use rand and srand and you know they'll work everywhere. Here's a link on portability. It discusses drand48.

http://www.opengl.org/resources/code/samples/sig99/advanced99/notes/node389.html

Look at this site for all your functions.

http://www.cplusplus.com

If it's not listed in the C++ libraries, consider it non-standard. use rand and srand instead if you want portability.

Edited 7 Years Ago by VernonDozier: n/a

my professor actually recommends that we use the drand48 function, I don't think i'm having an issue with that though. Rather the problem seems to be my use of the pure virtual function and creating my object


animShapeO.cpp:25: error: cannot allocate an object of abstract type 'animShapeO'

my professor actually recommends that we use the drand48 function, I don't think i'm having an issue with that though. Rather the problem seems to be my use of the pure virtual function and creating my object


animShapeO.cpp:25: error: cannot allocate an object of abstract type 'animShapeO'

Unless you have revised the code thoroughly beyond just correcting the error I pointed earlier regarding capitalization and haven't posted the new code, you have errors long before line 25, and these are errors that have nothing to do with the polymorphism or the fact that you are dealing with virtual functions. They are basic errors dealing with improper use of the dot operator, then when that is fixed, trying to access non-existent data members, then when that is fixed, trying to illegally access a protected data member from outside the class. All this is in line 21, well before line 25.

Start commenting out lines in main till you get it to compile then uncomment them a little at a time and debug. You may well have virtual function problems, but you have many others as well.

Edited 7 Years Ago by VernonDozier: n/a

I have been revising my code and believe I've fixed the use of my virtual function. But I am still having errors with accessing member functions of my base class. Here is my revised code:

DRIVER PROGRAM

#include "animShapeO.h"
#include <iostream>
#include <vector>
using namespace std;

double X,Y,height,width;
int minDim = 5, maxDim = 45;
int numRects;


int main()
{

cout << "how many rectangles do you want to create?" << endl;
cin >> numRects;

vector<double> rect (numRects);
vector<double> directionX (numRects);
vector<double> directionY (numRects);



  for(int i=0;i<numRects;i++)
  {
    animShapeO* rect[i];
    rect[i] = new animShapeO();
    X = drand48() * 640;
    Y = drand48() * 480;
    width = minDim + drand48() * (maxDim - minDim);
    height = minDim + drand48() * (maxDim - minDim);
    rect.getRect(X,Y,width,height);
    rect.setRect(X,Y,width,height);
  }


  for(int i=0;i<numRects;i++)
  {
    directionX[i] = -5 + drand48() * 10;
    directionY[i] = -5 + drand48() * 10;
    rect[i].update(directionX, directionY);

    cout << "rectangles      " << "number of rectangles left" << endl;
  for(int i=0;i<numRects;i++)
  {
    cout << rect[i].getRect() << endl;
  }
}

}

ANIMSHAPEO.H

#ifndef ANIMSHAPEO_H
#define ANIMSHAPEO_H
#include "shapeO.h"
#include <string>
#include <fstream>
using namespace std;

class animShapeO : public shapeO
{
        private:
        double directionX, directionY;

        public:
        virtual  bool collidesWith( shapeO *)
        {
          if (y > y + height)
            return true;
            else
            return false;
        }
//      update();
//      {
//        rect.

};
#endif

SHAPEO.H

#ifndef SHAPEO_H
#define SHAPEO_H
class shapeO {
public:

        shapeO() {};
        virtual ~shapeO() {};

    virtual  bool collidesWith( shapeO *) = 0 ;
    void getRect(double & X, double & Y, double & W, double & H)
        {  X = x; Y = y; W = width; H = height; }
    void setRect(double X , double Y, double W, double H)
        { x = X; y = Y; width=W; height=H;}
protected:
    double x,y, height, width;
};
#endif

Here are the errors i'm getting on compiling:

animShapeO.cpp: In function 'int main()':
animShapeO.cpp:31: error: request for member 'getRect' in 'rect', which is of non-class type 'animShapeO* [(((long unsigned int)(((long int)i) - 1)) + 1u)]'
animShapeO.cpp:32: error: request for member 'setRect' in 'rect', which is of non-class type 'animShapeO* [(((long unsigned int)(((long int)i) - 1)) + 1u)]'
animShapeO.cpp:40: error: request for member 'update' in 'rect. std::vector<_Tp, _Alloc>::operator[] [with _Tp = double, _Alloc = std::allocator<double>](((long unsigned int)i))', which is of non-class type 'double'
animShapeO.cpp:45: error: request for member 'getRect' in 'rect. std::vector<_Tp, _Alloc>::operator[] [with _Tp = double, _Alloc = std::allocator<double>](((long unsigned int)i))', which is of non-class type 'double'

One, it's a bad idea to name your driver program animShapeO.cpp. Any file with that name should be the name of the implementation file of your animShapeO class and shouldn't have a main function. You have the implementation in animShapeO.h, so you shouldn't have a file called animShapeO.cpp at all. Rename your driver driver.cpp or main.cpp or something. The compiler couldn't care less, but we humans get confused.

Two, it's a REALLY bad idea to use the same name for completely different variable types, as you do with rect . On line 17, it's a vector having to do with doubles. On line 25, it has to do with your animShapeO class. Line 40 presumably intends to refer to the declaration in line 25, but that's gone out of scope, so it actually refers to the declaration in line 17, which is a vector of doubles and has absolutely nothing to do with your class. Lines 31 and 32 are getting confused as to whether rect refers to a single object or an array.

Most of this confusion will go away if you rename your vector of doubles on line 17 to something besides rect. You'll still get plenty of errors, but it'll be more obvious what everything is intended to refer to. It isn't right now.

Edited 7 Years Ago by VernonDozier: n/a

Ok I've changed some things and believe I am able to create my derived objects and use the base class functions and variables. What I am having trouble with now is outputting my derived classes variables (the x and y locations and height and width). neither using the dot operator "rectangles.x" or the pointer which is what I am assuming I am supposed to use is working "rectangles.y". Thanks again I appreciate all the help.

DRIVER/MAIN

#include "animShapeO.h"
#include <iostream>
#include <vector>
using namespace std;

double X,Y,height,width;
int minDim = 5, maxDim = 45;
int numRects;


int main()
{

cout << "how many rectangles do you want to create?" << endl;
cin >> numRects;

vector<double> rectangles (numRects);
vector<double> directionX (numRects);
vector<double> directionY (numRects);

  for(int i=0;i<numRects;i++)
  {
    animShapeO* rectangles[i];
    rectangles[i] = new animShapeO();
    rectangles[i]->getRect(X,Y,width,height);
    X = drand48() * 640;
    Y = drand48() * 480;
    width = minDim + drand48() * (maxDim - minDim);
    height = minDim + drand48() * (maxDim - minDim);
    rectangles[i]->setRect(X,Y,width,height);
  }

//rectangles.showRectangles(numRects);

//  for(int i=0;i<numRects;i++)
//  {
//    directionX[i] = -5 + drand48() * 10;
//    directionY[i] = -5 + drand48() * 10;
//    rectangles[i]->update(directionX, directionY);
//    }
}

ANIMSHAPEO/H

#ifndef ANIMSHAPEO_H
#define ANIMSHAPEO_H
#include "shapeO.h"
#include <string>
#include <fstream>
#include<iostream>
using namespace std;

class animShapeO : public shapeO
{
        private:
        double directionX, directionY;

        public:
        virtual  bool collidesWith( shapeO *)
        {
          if (y > y + height)
            return true;
            else
            return false;
        }
//      void showRectangles( shapeO *, int numRects)
//      {
//        cout << "rectangles      " << "rectangle location" << endl;
//        for(int i=0;i<numRects;i++)
//        {
//          cout << " rectangle #" << i <<  rectangles[i].x << "  " << rectangles[i].y endl;
//        }
//        }

//      update();
//      {
//        rect.

};
#endif

SHAPEO.H

#ifndef SHAPEO_H
#define SHAPEO_H
class shapeO {
public:

        shapeO() {};
        virtual ~shapeO() {};

    virtual  bool collidesWith( shapeO *) = 0 ;
    void getRect(double & X, double & Y, double & W, double & H)
        {  X = x; Y = y; W = width; H = height; }
    void setRect(double X , double Y, double W, double H)
        { x = X; y = Y; width=W; height=H;}
protected:
    double x,y, height, width;
};
#endif

You did the same thing as you did before, only now instead of naming both your vector of doubles and your array of animShapeO rect , you've named them both rectangles . They need to have different names.

Also, if you want to use the variable that you define in line 23 after line 31, you need to put it before the for-loop, not inside of the for-loop. It's a scoping issue.

Edited 7 Years Ago by VernonDozier: n/a

Ok I see what your saying now. What I was trying to do was create a vector of animShapeO objects and not a vector of doubles and an array of objects. I'm not sure how to do this as I have tried:

vector<animShapeO> rectangles;
vector<animShapeO> rectangles (numRects);
vector<shapeO> rectangles;
vector<shapeO> rectangles (numRects);

and all of them return the error:

main.cpp:23: error: no match for 'operator=' in 'rectangles. std::vector<_Tp, _Alloc>::operator[] [with _Tp = shapeO, _Alloc = std::allocator<shapeO>](((long unsigned int)i)) = (((animShapeO*)operator new(56u)), (<anonymous>->animShapeO::animShapeO(), <anonymous>))'

I'll reiterate what I said in post 7. Please read it again. I think you need to set this assignment aside and take some tutorials on classes, vectors, dynamic memory, polymorphism. You also need to post much cleaner code and be a little more careful to spot things like multiple variables with the same name and capitalization. The former, in particular, is a recipe for disaster if you're not extremely careful. Also, with multiple files, in addition to posting the files, upload a zip file of the files along with a makefile and/or instructions on how to compile. It makes things much quicker for us and we know exactly what you're doing it. We can sometimes spot errors much more quickly. Get stuff like drand48 out of there because we just have to convert it to rand if we're not using the same compiler. Stick it back in there later, but make it easy and quick as possible for us please.

Without a firm understanding of polymorphism with non-abstract classes and functions, you can't understand what making classes and functions abstract does, so again, tutorials on polymorphism till you understand it, then try to tackle the abstract classes. Experiment. Experiment. Experiment. This all takes time and you need to be willing to put that time in (I'm not suggesting that you are not). Learn all that stuff, then come back to the project and see if it makes sense. Good luck.

This article has been dead for over six months. Start a new discussion instead.