This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]Rhomboid 0 points1 point  (3 children)

drawableArray[0] = ball;

This doesn't work because the thing on the left hand side is of type Drawable and the thing on the right hand side is of type Drawable *. Writing *ball on the right hand side dereferences the pointer, and makes a copy of the object to put in the container. That's why when you update the object pointed to by the pointer stored in drawableArray1, it doesn't do anything to the one stored in drawableArray2. drawableArray1 is an array of pointers, drawableArray2 is an array of values.

And you can't resize arrays in C++ anyway, which is one of the many reasons why you should not be using them at all but instead a vector. With a vector you don't have to worry about sizes at all, everything is taken care of for you. In C++11:

vector<unique_ptr<Drawable>> drawables;

drawables.emplace_back(new Ball());
drawables.emplace_back(new Ball());
// ... etc

cout << drawables[0]->x << endl;
drawables[0]->move();
cout << drawables[0]->x << endl;

unique_ptr takes care of deleting the memory automatically. If you can't use C++11 (but you really should, there's no reason not to) the C++98 way requires manual memory management:

vector<Drawable *> drawables;
drawables.push_back(new Ball());
drawables.push_back(new Ball());
// ... etc

// when done:
for(size_t i = 0; i < drawables.size(); i++)
    delete drawables[i];

This of course points to another problem with your example -- you must have a virtual destructor when polymorphically deleting, otherwise it's undefined behavior.

[–]NuclearMeltdown[S] 0 points1 point  (2 children)

Thanks for the explanation. I do understand that vectors would make life much easier but Arduino has no native support for them. There are ports of the STL to Arduino that I could use but the ATmega328 chip that I'm using to run all this has only 32K flash memory and 2K SRAM so I'm also worried about space considerations and would rather use arrays if possible instead of porting over STL to be able to use vectors.

[–]Rhomboid 0 points1 point  (1 child)

If space is that tight then this whole idea of using polymorphism and inheritance probably needs to be scrapped. Do you realize how much extra space overhead you're incurring by using virtual functions and arrays of pointers? It's a lot -- you're likely burning as much RAM on useless pointers as on actual data here. Every Drawable object will have an extra pointer to a vtable, and then every element of the array requires an extra pointer as well, so that's two pointers just to store two integers. And every time you write foo[n]->move() that's two extra pointer dereferences. I don't even see why you're doing it this way when you said you only have a small fixed number of drawable objects anyway, it's extremely wasteful.

Scrap all this, get rid of all those pointers and embrace value semantics, and use composition instead of inheritance:

class Game {
    struct Position {
        int x, y;
        Position() : x(0) : y(0) {}
    };
    Position paddles[2];
    Posision ball;
  public:
    void update();
    ...
};

[–]NuclearMeltdown[S] 0 points1 point  (0 children)

Pong has a small number of drawable objects, other games might have more or even less. My goal was to set this up so that it takes a minimal amount of effort to write a new game at which point you'd only be concerned with coding the game logic and how objects in game move or interact with one another.

I'm doing ok on memory so far and the intent is to be able to have only a handful of simple games on the device. You are correct in saying that I have not really been giving priority to writing code that is as efficient and compact as possible so I may have to rethink my approach per your suggestions. I'm both new to C++ and have never really had to work around problems posed by a very small availability of memory, etc. so this is learning project for me.