1

This problem has been confusing me for quite some time now.

Bascily I need to be able to individually access multiple objects by their name in another function. Ive seen examples where object pointers are pushed into a list but I cant access them by their name that way it seems.

Lets say in one function I create many objects (both hardcoded and dynamically allocated), then in another I use all the objects (draft code btw)

class gameobjects
{
public:
    float x = 0.0f;
    float y = 0.0f;
    float z = 0.0f;
};
void createenemies()
{
    gameobjects* chief = new gameobjects();
    chief->x = 1.0f;

    gameobjects* grunt = new gameobjects();
    grunt->x = 4.0f;

    gameobjects* elite = new gameobjects();
    elite->x = 8.0f;

}

void scene()
{
    ---
    chief->x = 9.0f;
    ---
    elite->x = 4.0f;

    grunt->y = 8.0f;
    ---
}

Looking online I cant seem to be able to find a solution to this problem. The class and the function is in the same source file. Ive tried researching how to acess multiple objects by the name in another function, and how to make functions global. Thanks for any help.

edit: Im looking for a way to keep my code neat and up to good standards with just one function that can both dynamically and hardcodely create objects of which can be accessed throughout the program.

edit: Passing through each object to another function wont really be practical in some cases where If want to create many or even hundreds of objects in the createenemiesfunction

J. Doe
  • 171
  • 4
  • 11

2 Answers2

2

From a design perspective, put things that belong together logically into a single context. Furthermore, avoid dynamic allocation if not necessary.

struct EnemyScene {
  GameObject chief;
  GameObject grunt;
  GameObject elite;
};
inline EnemyScene createScene() {
  // You also may want to consider making this function
  // a constructor of EnemyScene if you don't have a lot
  // of different ways to create Scenes.
  EnemyScene es;
  es.chief.x = 1.0f;
  es.grunt.x = 4.0f;
  es.elite.x = 8.0f;
  return es;
}
inline void updateScene(EnemyScene& es) {
  es.chief.x = 9.0f;
  es.elite.x = 4.0f;
  es.grunt.y = 8.0f;
}
inline void example() {
  EnemyScene es = createScene();
  updateScene(es);
}

You might think that copying the EnemyScene object around is bad, and you wouldn't be wrong in general. However, compared to a single memory allocation copying a bunch of integers is extremely cheap. Furthermore, due to enforced NRVO, createScene doesn't even lead to any copy whatsoever.


If you need to keep the object around and cannot, I repeat cannot, use automatic memory to allocate it, you can instead choose to keep it in a dynamically allocated object:

inline std::shared_ptr<EnemyScene> createSharedScene() {
  return std::make_shared<EnemyScene>(createScene());
}
inline void example2() {
  std::shared_ptr<EnemyScene> ptr = createSharedScene();
  // ...
  updateScene(*ptr);
}
bitmask
  • 32,434
  • 14
  • 99
  • 159
-1

scene doesn't know the instancee created in createenemies because they have different scopes, your three objects won't exiss after }.

There are several ways to deal with this. For exaple:

void createenemies(gameobjects *& chief, gameobjects *& grunt, gameobjects *& elite)
{
    chief = new gameobjects();
    chief->x = 1.0f;

    grunt = new gameobjects();
    grunt->x = 4.0f;

    elite = new gameobjects();
    elite->x = 8.0f;

}
void scene(gameobjects *& chief, gameobjects *& grunt, gameobjects *& elite)
{
    ---
    chief->x = 9.0f;
    ---
    elite->x = 4.0f;

    grunt->y = 8.0f;
    ---
}

int main(){

gameobjects * chief;
gameobjects * grunt;
gameobjects * elite;

createenemies(chief, grunt, elite);
scene(chief, grunt, elite)

return 0;
}

In this case, we create 3 pointers of type gameobjects and in the same scope passed them to both functions.

Note that this wouldn't work:

int main(){

{
gameobjects * chief;
gameobjects * grunt;
gameobjects * elite;
} //The pointers no longer exists

createenemies(chief, grunt, elite);
scene(chief, grunt, elite)

return 0;
}
Ivan
  • 1,352
  • 2
  • 13
  • 31
  • This might not be a concern for u now. but be aware that passing pointers can be a bad idea in some cases [and you can also pass references](https://stackoverflow.com/questions/620604/difference-between-a-pointer-and-reference-parameter) – Ivan Jul 29 '21 at 17:03
  • 2
    Warning: This answer requires an extra level of indirection in `createenemies`. Parameter `gameobjects * chief` passes whatever `chief` points at by reference, but the pointer itself is passed by value. `chief = new gameobjects();` updates a local variable and the caller will be totally unaware. The `gameobjects` is allocated and then promptly leaked. You need `gameobjects *& chief` to be able to update the caller. – user4581301 Jul 29 '21 at 17:14
  • This will not work. It will in fact very likely segfault because you are not passing the pointers themselves as reference. – bitmask Jul 29 '21 at 17:22