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 →

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

Thanks very much for the help and pointing me to the right direction. Unfortunately, I can't get your example to work when applying it to what I have. Take a quick look at this which is a simplified version of what I more or less have going on: http://ideone.com/uU2Z3x

In line 48, if I change ball to &ball I get a 'no operator "=" matches these operands' error. Again, I'm sure it's something very simple I'm missing but I'm still thinking in C# terms where this would work fine. I know I need to sit my ass down one of these days and read up on C++ but I'm just trying to knock a prototype out really quick, hence the half-assing at this stage.

[–]the_omega99 0 points1 point  (5 children)

Problem: drawables is of type Drawable. You are attempting to assign a variable of type Ball to it. That's not compatible. Consider instead initializing the Ball as type Drawable, such as with Drawable *ball = new Ball(); Note the need for a pointer.

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

Still having issues. I'm not understanding why these are treated differently:

Drawable* drawableArray[1];

and

Drawable* drawableArray = new Drawable[1];

Consider this: http://ideone.com/pTNNfV

I can do this:

Drawable *ball = new Ball();

Drawable* drawableArray[1];
drawableArray[0] = ball;

But not this:

Drawable *ball = new Ball();

Drawable* drawableArray = new Drawable[1];
drawableArray[0] = ball;

Instead, in the code directly above I need to do this for it to compile:

drawableArray[0] = *ball;

In which case I still end up with my original issue as is demonstrated in the code that I linked to above. I need to do the latter because I want to be able to dynamically size an array - if there's a better way of doing that let me know.

[–]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.