Add Object to Array from Constructor

Started by
7 comments, last by Fl00Fy 11 years ago

Hey

I'm trying to implement collision detection for a project. So far, my idea has been to add all objects that are added into a scene into an array of objects. My question is, as in the title, can I add an object to said array in its constructor?

I've tried like this


Object::Object () 
{
	pos_x = 0; pos_y = 0; velocity = 0; direction = 0;
	objectArray [numObjects] = this.Object;
        numObjects++
}

and this


Object::Object () 
{
	pos_x = 0; pos_y = 0; velocity = 0; direction = 0;
	objectArray [numObjects] = this;
        numObjects++
}

But neither worked, and I'm having trouble figuring out exactly how I would do it properly, if it's at all possible.

Also, objectArray is just a pointer to an object, and I've had trouble with pointers before (and probably will for a while).


int numObjects = 0; 

Object *objectArray;

Any help would be appreciated. I also realise that there are probably better ways to keep track of all the objects, or to go about handling collision detection in general. So any help with this topic, or just collision detection in general would be great.

Thanks.

Advertisement

You can, but the array has to be static. Also, by 'array', it's much better to use a std::vector.

So like:


class Object
{
    private:
    std::vector<Object*> AllObjects; //A vector of pointers.
 
    public:
    Object()
    {
         Object::AllObjects.push_back(this);
    }
 
};

However, you have the problem that you'd have to remove objects from the array when the object is destroyed (otherwise you'd still have pointers to objects that no longer exist).

It might be better to have the collision between two objects be managed by outside of the Object's themselves, and that the array of Objects are also outside of the Object class, and the array isn't an array of pointers, but an array of the actual object instances themselves.

An Object shouldn't know whether other Objects exist, unless it "owns" the other Objects or is related to them (as children or parents or whatever).

Thanks for the help. I was actually considered using std::vector, and now that you mention it, it would be very useful when deleting objects. The array I created wasn't part of the object, I just needed it to be modified from within the Object class. I assume that if the vector is of actual objects and not pointers, it wouldn't make sense to add objects to the array in the constructors and end up having duplicates of all objects (those created normally and those then added to the array), but simply create the objects in the array, is that correct?

And thanks again for the help

Yes that is correct, you wouldn't add them from their constructors if the array actually owns the objects.

If you think in terms of ownership:

Something owns an std::vector that owns the Objects. The Objects don't know about each other. Whatever owns them knows about all of them, and can handle the interactions between them using the functions the Objects provide.

For example, to test if one Object is colliding with another, you might have a function in Object that takes another Object (by const reference*) as a parameter.

The class that owns all the Objects can pass one Object as a parameter of another's function.

bool Object::IsColliding(const Object &anotherObject) const
{
     return /* ...check if 'this' object is overlapping with 'anotherObject'... */
}

Object objectA;
Object objectB;
 
if(objectA.IsColliding(objectB))
{
    //...
}

So the 'objectA' doesn't know that 'objectB' exists, though it knows that other Objects *could* exist, and can take them by parameters for temporary work, but shouldn't keep track of the other Object for longer than the duration of that one function call.

*A reference, because you aren't wanting to create a copy, and const because - in this case - you aren't wanting to modify the Object passed in.

Alright. That's great. Thank you. You've been a great help.

If your vector owns the object pointers, use a unique_ptr<Object>, then cleanup happens automatically.

If this post or signature was helpful and/or constructive please give rep.

// C++ Video tutorials

http://www.youtube.com/watch?v=Wo60USYV9Ik

// Easy to learn 2D Game Library c++

SFML2.2 Download http://www.sfml-dev.org/download.php

SFML2.2 Tutorials http://www.sfml-dev.org/tutorials/2.2/

// Excellent 2d physics library Box2D

http://box2d.org/about/

// SFML 2 book

http://www.amazon.com/gp/product/1849696845/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=1849696845&linkCode=as2&tag=gamer2creator-20

Thanks. I'll definitely look into it.

Would it be best used as a vector containing unique_ptrs to Objects, as in


std::vector<std::unique_ptr<Object>> AllObjects; 

... possibly..... or as a dynamically-allocated array of Objects, like std::unique_ptr<Object[]>... possibly.

Would I be correct in assuming the first one is better? Since it would handle individual objects that need deleted better.

std::vector<Object> is perfectly fine if Object isn't too large in memory (it's member-variables count towards the memory, but not non-virtual functions). If Object has less than, say, 10 member variables, I'd recommend to just do std::vector<Object>.

std::vector<std::unique_ptr<Object>> would be good if Object is very large (very large), or if you need to hold Objects that are in some way 'null' in the vector. But you can just do that with a member variable of Object anyway if it makes sense to the class.

std::unique_ptr<Object[]> wouldn't be a good idea (it might not even compile, but I'd have to check). Everything it offers, std::vector<> also offers, but std::vector is designed for the purpose of dynamic arrays and std::unique_ptr isn't.

To avoid any confusion, std::vector calls the destructor of Objects just like std::unique_ptr does; and both by default hold the Object in dynamic memory. Both also cleanup after themselves. But if std::vector is holding normal pointers instead of instances, then it won't clean up what the pointer points to. (std::unique_ptr is an instance that contains a pointer, which it cleans up in its destructor, so it's cleaned up).

std::vector<Object> = cleaned up.

std::vector<Object*> = The memory the pointers point to are not cleaned up.

Ah ok. std:vector of objects it is. Thanks again for all the help.

This topic is closed to new replies.

Advertisement