2016-03-20 4 views
0

Ich arbeite an einer Simulation von Arten, wo es einen Spieler in einer 2D Welt von Blöcken gibt. Die vielen Blockobjekte sind in einem Vektor gespeichert, und jeder hat ein Element, das eine Referenz auf diesen Vektor ist, so dass jeder durch die anderen iterieren kann, um Dinge wie Kollisionen zu behandeln. Um die Physik des Spielers mit den Blöcken zu vereinfachen, habe ich die Player-Klasse von der Block-Klasse erben lassen. Während dies die Physik viel einfacher macht, bin ich auf das Problem der Unfähigkeit gestoßen, eine Spielermitgliedfunktion aufzurufen, während ich auf den Spieler vom Vektor verwiesen habe.Aufruf einer Memberfunktion eines geerbten Vektorelements

Hier sind einige vereinfachte Versionen der Klassen:

class Block{ 
private: 
    std::vector<Block>& blocks; 
public: 
    Block(std::vector<Block>& b) : blocks(b) {} 
}; 

class Player : public virtual Block{ 
public: 
    Player(std::vector<Block>& b) : Block(b) {} 
    void player_only_function(); 
}; 

std::vector<Block> blocks; 
Player player(blocks); 
blocks.push_back(player); 

blocks[0].player_only_function(); // This line in incorrect 

Gibt es eine einfache Möglichkeit, dies zu umgehen?

+0

* "Ich habe die Player-Klasse von der Block-Klasse geerbt" * - Das klingt nicht richtig. Öffentliche Vererbung modelliert eine IS-A-Beziehung, und ein Spieler ist kein Block. –

Antwort

0

Es ist nicht möglich, wenn Sie nur einen Vektor von Block Objekten haben, und dann haben Sie Objekt schneidet wenn Spielzeug Push-back Ihr Player Objekt.

Stattdessen müssen Sie Zeiger und etwas namens downcasting verwenden. Wie

std::vector<Block*> blocks; 
blocks.push_back(new Player(blocks)); 

static_cast<Player*>(blocks[0])->player_only_function(); 

Allerdings müssen Sie darauf achten, dass die niedergeschlagenen Sie tatsächlich gültig zu machen ist, und dass blocks[0] ist ein Zeiger auf ein Objekt Player.

+0

Ich sehe. Wenn ich 'blocks' einen Vektor aus 'Block *' s mache und 'blocks.push_back (& ​​player)' mache, kann ich dann 'player.player_only_function()' einfach aufrufen, anstatt zu werfen? –

+0

@KaiSchmidt Denken Sie ein wenig über das, was Sie gerade geschrieben haben, das Rufen von 'player_only_function' auf dem' player' Objekt wird immer möglich sein. :) Wenn Sie Zeiger auf die Basisklasse verwenden möchten, müssen Sie umwandeln. Wenn Sie jedoch '& player' zurückdrängen, müssen Sie über die Lebensdauer von' player' nachdenken. Wenn 'player' zerstört wird, bevor Sie den Zeiger verwenden, ist der Zeiger nicht mehr gültig. –

+2

Wenn man wie diese tatsächlich abwertet, dann wird der Punkt, eine Klassenhierarchie (d. H. Eine Basisklasse und abgeleitete Klassen) zu haben, häufiger zunichte gemacht. Suchen Sie nach Möglichkeiten, erforderliche Funktionen (z. B. reine virtuelle Systeme) in der Basisklasse bereitzustellen, und nutzen Sie stattdessen Polymorphismus aus. – Peter