Creating several instances of an object during program run

Greetings all

I have a question regarding dynamically allocating new instances of objects during the program run. For example, in a game like GTA, depending on what is happening and where the player is, there are new cars appearing (and disappearing).

How do you keep making new 'car' instances, and at proper moments delete specific ones? I imagine the code to create a new 'car' would look something like this:

1
2
3
4
5
6
class car;

void CreateNewCar()
{
car* SomeNewCar = new car;
}


But you would always create an instance with same name. This can't work too well. What is the solution to this problem? How are instances allocated during the run of the program? Question and answer can be generalized beyond this game and 'car' example.

Thank you and kind regards,
T


Last edited on
The answer is polymorphism

The Mercedes and Jeep are all cars. How do you know which one to spawn at the appropriate time.
Also, If you have animals in a zoo, and want to say MOVE. How do you make the MOVE command to execute in the appropriate form. Because a snake will move differently from a monkey.

All of these problems are solve by the paradigm mentioned above.

Polymorphism is the phenomenon where the same command executes in several different forms.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
#include <string>

using namespace std;

class Animal
{
public:
	//pure becuase a Animal cannot walk on its own. (WHAT ANIMAL ARE YOU??)
	virtual void MOVE() = 0;
};
class Snake : public Animal
{
public:
	//override
	void MOVE()
	{
		cout<<"I am crawling"<<endl;
	}
};
class Monkey : public Animal
{
public:
	//override
	void MOVE()
	{
		cout<<"I am skipping and jumping and walking"<<endl;
	}
};

int main()
{
	Animal *animals[2];
	
	animals[0] = new Snake();
	animals[1] = new Monkey();

	for(int i = 0; i < 2; i++)
		animals[i]->MOVE();	//LATE BINDING.
		
	cout<<endl;
	return 0;
}


You see that the same command animals.MOVE produces different outcomes.

That is what happens in GTA
I don't think you touched the core of my question, or maybe didn't understand it. I can't blame you, I didn't write my question well and was afraid it would get misunderstood.

Maybe using your code will help. in your main there is:

1
2
3
4
Animal *animals[2];
	
	animals[0] = new Snake();
	animals[1] = new Monkey();


But in this case you know you want to create one new Snake and one new Monkey. But how do you do that in the game, when you don't know ahead how many instances you will need, and at what times?
Extending on ShadowCODE's example,

> How do you keep making new 'car' instances, and at proper moments delete specific ones?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main()
{
	Animal *animals[2];
	
	animals[0] = new Snake();
	animals[1] = new Monkey();

	for(int i = 0; i < 2; i++)
		animals[i]->MOVE();	//LATE BINDING.

	// Do stuff with your animals

	for(int i = 0; i < 2; i++)
		delete animals[i]; // Free the memory allocated
		
	cout<<endl;
	return 0;
}
The game is interactive either with you or with the story line.

you allocate memory on the fly as you need.

Case 1: Story Line.
Assume my example above is part of a story line where when my character enters a certain place, a snake and a monkey have to be created. That's settled.

Case 2: Human interaction.
You actions determine what objects and how many instances to create.
If on the mouse you shoot the opponent with a left mouse click, a bullet object will be created the number of times you press the button.
+1 to megatron 0 for pointing out clean up
Thank you for your explanations. But I still have some trouble understanding, how I would go about implementation.

Bullets are a good example. There's no way of telling how many bullets and when they would be created.

Do you store a new bullet in a vector each time one is fired? And on every "delta T" you iterate through that vector and change their position or delete ones not needed anymore?

It's kind of an implementation detail question I guess. But I wonder how these things are done in practice, I would not want to end up doing some implementation on my own, that would be complicated and resource wasteful.
I would also like to add in your original post you defined a function that would create a car object, a void function. As soon as that function is called a memory leak occurs. After the function is returns car* SomeNewCar is inaccessible I believe ( it is 2:40am ) and you have "leaked memory".

My second note is creating a function like that is called The Factory Method, but instead of a void function, it would return type car*.

1
2
3
4
5
6
7
8
9
car* CreateCar(/* Car object arguments */)
{
	return new Car(/* args */)
}

void DeleteCar(car** c)
{
	delete *c; // IIRC
}


EDIT:

> Do you store a new bullet in a vector each time one is fired? And on every "delta T" you iterate through that vector and change their position or delete ones not needed anymore?

Sure, or depending on the game physics you could "look ahead" without doing calculations through every time iteration.
Last edited on
> Do you store a new bullet in a vector each time one is fired? And on every "delta T" you iterate through that vector and change their position or delete ones not needed anymore?

Depends on you.
@megatron 0
Can you please explain me what "look ahead" is? I did a quick search and found out the term is used in programming, but couldn't find the explanation (yet).

@shadowCODE
You are right, it depends on me if I will make a good implementation =) That's why I am asking how it is usually done, and considered effective and safe. Because I have no experience with it yet.
> Can you please explain me what "look ahead" is?

I'm very tired and I don't want to give you bad info so I urge you look it up. Imagine playing chess, the opening is all about planning an attack luring your opponent into a false sense of security, those moves you make you attempt to look ahead, see into the future and estimate a possible combinations of moves to be made and either avoid them or use them to your advantage.

Computers in a sense, can see into the future but only through a programs perception of time. When you fire that bullet, you could spawn a thread of a "dummy" bullet, that is half a second in front, which can signal to other parts of your program of possible event conditions.
Alright, thanks a lot mate. Get some proper well deserved rest! :D
You are very welcome, happy coding :) goodnight sir.
Thor36, the answer to your original question is that either (1) you allocate an array of objects and the array can be different sizes, or, more commonly (2) the object that you allocate has one or more pointers itself.

A simple example is a linked list of integers. An item in the list contains an integer and a pointer to the next time:
1
2
3
4
struct Item {
    int i;
    Item *next;
};


The program contains a variable that points to the first item:
Item *head;

You add items to the linked list like this:
1
2
3
4
5
6
7
void addItem(int i)
{
    Item *newItem = new Item();
    newItem->i = i;
    newItem->next = head;
    head = newItem;
}


Now the program has just one variable (head), but the it can have any number of items, all accessible through the one head variable.
Topic archived. No new replies allowed.