2

I have two classes called Player and Enemy both inheriting from a class called GameObject, how do I store them both in an array of type GameObject while still keeping their own unique information?

I tried making an array like this:

std::vector<GameObject> _gameObjList;

and then tried pushing a test object in it like this:

testObject test;
_gameObjList.push_back(test);

but then it gave me the following exception error:

Error C2664 'void std::Vector<GameObject *,std::allocator<_Ty>>::push_back(_Ty &&)': cannot convert argument 1 from 'testObject *' to 'GameObject *const &' OpenGLFramework c:\users\name\projects\myproject\gamemanager.cpp 11

so basically it's saying that the types should be the same, even though my testobject inherits from GameObject.

Here is my testObject header file:

#pragma once

#include "GameObject.h"

class testObject : public GameObject
{
public:
    testObject();
    testObject(float xPosition, float yPosition, float zPosition);

    void Update();

    ~testObject();
};

There isn't really anything in the cpp file that goes with it except the constructor and update method but those are all empty at the moment so I don't think it's necessary to show them here.

I hope anyone here can explain me the proper way to do this and/or can point out the error(s) in my code. I just want to have an arraylist of all my gameobjects so I can add/remove objects easily.

closed as off-topic by candied_orange, Christophe, Greg Burghardt, gnat, Deduplicator Jul 27 '18 at 6:33

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions asking for assistance in explaining, writing or debugging code are off-topic here. These can be asked on Stack Overflow if they include the desired behavior, a specific problem or error, and the shortest code necessary to reproduce it in the question (see Minimal, Complete, and Verifiable Example)." – Christophe, gnat
If this question can be reworded to fit the rules in the help center, please edit the question.

4

Use std::vector<std::shared_ptr<GameObject>>

std::vector<std::shared_ptr<GameObject>> v;
v.push_back (make_shared<Player> ());
v.push_back (make_shared<Enemy> ());

If you want your code to look more like you are directly using Player, Enemy, and GameObject, you can introduce typedefs:

using GameObjectP = shared_ptr<GameObject>;
struct PlayerP : shared_ptr<Player> {
    PlayerP() : shared_ptr<Player> {make_shared<Player> ()} {};
};
struct EnemyP: shared_ptr<Enemy> {
    EnemyP() : shared_ptr<Enemy> {make_shared<Enemy> ()} {};
};

std::vector<GameObjectP > v;
v.push_back (PlayerP ());
v.push_back (EnemyP());
  • 2
    When an owning pointer is needed, yes, smart-pinters are the tool of choice. But avoid shared ownership and all the associated complexity and cost until and unless you know it's necessary. – Deduplicator Jul 27 '18 at 6:16
3

Well, a std::vector<T> is a dynamic array of Ts, not of pointers to Ts or anything else.

So, we need a way to somehow store heterogenous objects.
Well, one can use a std::any or the more efficient std::variant if one knows all the options.
Or one can store pointers, preferably smart-pointers, which generally means std::unique_ptr or if you actually really need shared ownership std::shared_ptr.

Which alternative is best?
That depends on your specifics, look them over and choose.

-1

Initialize your player/enemy as your base type.

GameObject* obj = new Player();

You can now store it in your list. You need to cast it to a player object to be able to use the players methods/members. Look up the visitor pattern, very useful with this type of architecture.

Edit: do note that it's now a pointer and is heap allocated.

  • You might want to be a bit more explicit that the programmer now is responsible for managing its lifetime manually. – Deduplicator Jul 27 '18 at 6:33

Not the answer you're looking for? Browse other questions tagged or ask your own question.