Skip to main content
GameDev.net gamedev.net
🔒 Locked

Add Object to Array from Constructor

Started by Fl00Fy Apr 8, 2013 at 7:53 PM 7 replies 1.7k views
Original Post
Fl00Fy
Fl00Fy

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.

Servant of the Lord
Servant of the Lord

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).

Fl00Fy
Fl00Fy

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

Servant of the Lord
Servant of the Lord

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.

Fl00Fy
Fl00Fy

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

Fl00Fy
Fl00Fy

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.

Servant of the Lord
Servant of the Lord

std::vector 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.

std::vector> 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 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 = cleaned up.

std::vector = The memory the pointers point to are not cleaned up.

Fl00Fy
Fl00Fy

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

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.