Executing Dynamic Objects Member Functions - But they don't exist yet

Hello. First of all, I just want to say, thank you for taking the time to read this. I've been having a hard time figuring this particular thing out, and I have done some extensive searching with Google. Obviously the only reason I am posting about this, is because I simply can't find an answer. I'll try to make it brief.

I am trying to make a game in C++. This is what I'm trying to do.

I have a game loop.

Inside this game loop, I am calling the objects' member functions to update them.

1
2
3
player->update();
enemy[0].update();
enemy[1].update();


Now obviously I am using a loop to check through all of my enemy objects. I'm just trying to illustrate my point.

I am using a 2D array for my level. And certain numbers represent tiles, and certain numbers represent the enemies, and player, etc.

For instance, the number 2 is the player, and the multiple number 3s represent the enemies.

I have a loop that reads through this array, and dynamically creates these objects, so I am using them only when I need them, and deleting them when the player beats the level, and creating new ones when the next level is called, etc. Another benefit of having my objects represented in the array, is that I can use the array to initialize their starting x and y positions.

My code counts how many enemies are in the array, and uses that count to dynamically create storage for that amount of enemies.

Here is the problem:

1
2
3
player->update();
enemy[0].update();
enemy[1].update();


The compiler will give you an error if you try to run these object member functions UNLESS the objects already exist.

I even tried something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
bool playerExists;
bool enemyExists;

if (playerExists)
{
   player->update();
}

if (enemyExists)
{
   for (int i = 0; i < enemyCount; i++)
	enemy[i].update();
}


I want to use dynamic objects to manage memory, but you can't run these member functions in the game loop unless they already exist.

So how do you set aside storage for an object, if you don't know in advance how many objects you're going to need (it's all based on how many objects are in the arrays for each level), and call their member functions?

I heard you can set objects with a NULL_PTR, but then, it still doesn't solve the problem.

Even if you create a single object at compile time, and set it to the null pointer, how do you then later modify it to dynamically set storage for more objects of that type?

Based on the searching I have done, there doesn't seem to be an answer.

I tried using vectors as well, and had some problems with them too. Since a vector is a dynamic array and can be resized.

I don't remember the specifics, but with one of my projects (and I dissected my own code to look for the error), I couldn't for the life of me figure out why using the vectors to create my objects were causing my program to not compile. I couldn't trace the error.

Just out of curiosity, if you have a vector of 3 enemy objects, and then you shrink that vector down to 2 enemy objects, what happens to the data in the third object? Does it still sit there in memory? What if you shrink it down to 2 objects, and then expand it back to 3 objects? Can it then use that data that was previously there?

I want to create these objects during runtime, when I need them, and still execute their update member functions every frame ONCE they are created.

The concept of dynamically creating objects is neat, but if they need to be defined first in order to use their functions later, doesn't that defeat the whole purpose of dynamically creating storage?

Thank you for taking the time to help me with this issue.
Last edited on
The compiler will give you an error if you try to run these object member functions UNLESS the objects already exist.
What do you mean by 'exist'? The compiler will only complain when it is not defined.

Consider this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
enemy_type* enemy = nullptr;
bool playerExists;
bool enemyExists;

if (playerExists)
{
   player->update();
}

if (enemyExists)
{
   enemy = new enemy_type[enemyCount];

   for (int i = 0; i < enemyCount; i++)
	enemy[i].update();
}
So based on your example, if I have two classes, Player and Enemy...

Instead of doing this:

1
2
Player player = new Player;
Enemy enemy = new Enemy;


I can do this?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//define first

Player * player = nullptr;
Enemy * enemy = nullptr;

//later on

player = new Player;
enemy = new Enemy[enemyCount];

//in game loop

player->update();
enemy[0].update();


I didn't know that you could make a dynamic array out of something that wasn't originally an array (if you know what I mean), and that is what I meant by "exists". Exists, as in, defined.

But then again I suppose that the first two lines above are not really variables per say, they are pointers.

I'm sorry, I'm still relatively new to pointers and dynamic arrays.

But this clears things up a bit.

Thank you so much coder777! :)
I don't entirely understand your problem. Maybe this will give you some ideas:

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
44
45
46
47
48
49
50
51
#include <iostream>
#include <vector>
using namespace std;

class Unit
{
public:
    void update()
    {
        cout << "update\n";
    }
};

Unit* player = nullptr;
vector<Unit*> enemies;

void update()
{
    cout << "==========\n";
    if( player ) player->update();
    cout << "----------\n";
    for( Unit* u: enemies )
        u->update();
}

void init_enemies( size_t num_enemies )
{
    for( size_t i = 0; i < num_enemies; ++i)
        enemies.push_back( new Unit );
}

void delete_enemies()
{
    for( Unit* u: enemies )
        delete u;
    enemies.clear();
}

int main()
{
    update();
    player = new Unit;
    init_enemies( 4 );
    update();
    delete_enemies();
    update();
    init_enemies( 2 );
    update();
    delete_enemies();
    delete player;
}

¿how many players do you have?
¿do you kill the player when you beat the level, just to revive it in the next one?
¿why is player a pointer?


> The compiler will give you an error if you try to run these object member
> functions UNLESS the objects already exist.
if you have an error, post the error verbatim

> I tried using vectors as well, and had some problems with them too.
> Since a vector is a dynamic array and can be resized.
¿what problems?
¿how is being able to resize giving you issues?

> I couldn't for the life of me figure out why using the vectors to create my
> objects were causing my program to not compile
in general, the compiler will give you an error message
so you have to read that error message
¿don't understand it? post it verbatim

> if you have a vector of 3 enemy objects, and then you shrink that vector down to 2 enemy objects,
> what happens to the data in the third object?
the object is destroyed

> Does it still sit there in memory?
¿does it matter?
(¿are you asking about .shrink_to_fit() perhaps?)

> What if you shrink it down to 2 objects, and then expand it back to 3 objects?
> Can it then use that data that was previously there?
no
¿why did you destroy it in the first place if now you want it back?
use vectors.

your pointer = null and memory later is fine. but vectors manage memory for you better and without the memory bugs that DIY code will often have.

Can you try again with vectors and show us what isnt working if you hit a snag?

read an in depth vector example or tutorial.
learn to presize them (so they have a good amount of memory up front and do not need to resize all the time when used). Learn how to do remove/erase pattern. Learn about size(). Learn about push_back. Learn about fixed initial size like array (different from presize. presize gives memory but size = 0 and vec[0] does not exist. initial size, size=n and vec[n-1] exists).

our site is a little dated but a few min here can still get you a long way.
https://cplusplus.com/reference/vector/vector/


its really unclear what you want, but static functions can do some things without having to create memory. This has a lot of limits, so it depends on what you are doing. Generally if you want an object, make an object, and avoid create/destroy time-wasting in favor of keeping it around to re-use where that makes sense.
Last edited on
Topic archived. No new replies allowed.