Come posso inserire oggetti di tipi diversi derivati da una base comune nello stesso array? [chiuso]

2

Ho due classi chiamate Player e Enemy che ereditano entrambe da una classe chiamata GameObject , come posso conservarle entrambe in un array di tipo GameObject pur mantenendo le proprie informazioni univoche?

Ho provato a creare un array come questo:

std::vector<GameObject> _gameObjList;

e quindi ho provato a inserire un oggetto test in questo modo:

testObject test;
_gameObjList.push_back(test);

ma poi mi ha dato il seguente errore di eccezione:

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

quindi fondamentalmente sta dicendo che i tipi dovrebbero essere gli stessi, anche se il mio testobject eredita da GameObject .

Ecco il mio file di intestazione testObject:

#pragma once

#include "GameObject.h"

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

    void Update();

    ~testObject();
};

Non c'è nulla nel file cpp che lo accompagna tranne il costruttore e il metodo di aggiornamento, ma sono tutti vuoti al momento quindi non penso sia necessario mostrarli qui.

Spero che qualcuno qui possa spiegarmi il modo corretto di farlo e / o indicare gli errori nel mio codice. Voglio solo avere un arraylist di tutti i miei oggetti di gioco in modo da poter aggiungere / rimuovere oggetti facilmente.

    
posta Thomas Linssen 27.07.2018 - 00:01
fonte

3 risposte

2

Usa 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> ());

Se vuoi che il tuo codice assomigli più a come usi direttamente Player, Enemy e GameObject, puoi introdurre typedef:

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());
    
risposta data 27.07.2018 - 00:31
fonte
2

Bene, un std::vector<T> è un array dinamico di T s, non di puntatori a T s o qualsiasi altra cosa.

Quindi, abbiamo bisogno di un modo per archiviare in qualche modo oggetti eterogenei.
Bene, si può usare un std::any o il più efficiente std::variant se si conoscono tutte le opzioni.
Oppure puoi memorizzare puntatori, preferibilmente puntatori intelligenti, che in genere significa std::unique_ptr o se in realtà hai bisogno di proprietà condivisa std::shared_ptr .

Quale alternativa è la migliore?
Dipende dalle tue specifiche, guardale e scegli.

    
risposta data 27.07.2018 - 00:24
fonte
-1

Inizializza il tuo giocatore / nemico come tipo di base.

GameObject* obj = new Player();

Ora puoi salvarlo nella tua lista. Devi lanciarlo su un oggetto giocatore per poter usare i metodi / membri del giocatore. Cerca il modello di visitatore, molto utile con questo tipo di architettura.

Modifica: si noti che ora è un puntatore e viene assegnato un heap.

    
risposta data 27.07.2018 - 00:29
fonte

Leggi altre domande sui tag