2016-11-04 4 views
1

I eine Art Hierarchie haben:Anrufverfahren für Objekte von abgeleiteten Typ

class GameObject{...}; 
class Subject:public GameObject{...}; 
class Player:public Subject{...}; 
class Bullet:public Subject{...}; 
class Enemy:public Subject{...}; 

in der Anordnung von Gameobject * durchqueren, überprüfe ich den Zustand und die Call-Methode foo (* object1, * object2) (object1 Referenz to Bullet, object2 ist ein Verweis auf Player).

std::vector<GameObject*> objects; 
// fill array (pointers to Bullet, Enemy, Player) 
foreach(auto obj1 : objects) 
{ 
    foreach(auto obj2 : objects) 
    { 
    if(obj1.getID() != obj2.getID() 
    { 
     foo(*obj1, *obj2); 
    } 
    } 
} 

Auch schreibe ich einige überladene foo Methoden:

void foo(GameObject&, GameObject&) 
void foo(Bullet&, Player&) 
void foo(Bullet&, Enemy&) 

Aber nur foo (Gameobject &, Gameobject &) genannt wird. Warum?

+1

Weil die Zeiger immer noch vom Typ 'GameObject' sind. So funktioniert Polymorphismus nicht. – AndyG

+0

Wenn Sie das Objekt als abgeleiteten Typ interpretieren möchten, müssen Sie den Basisklassenzeiger auf einen Zeiger der abgeleiteten Klasse hin "dynamic_cast". (Aber natürlich müssen Sie wissen, welcher abgeleitete Typ verwendet wird, wenn jedes Objekt geworfen wird, was den Zweck des Polymorphismus besiegt.) – 0x5453

Antwort

0

Dies sind Zeiger auf GameObject. Sie dereferenzieren sie und erhalten Objekte vom Typ GameObject, und das macht Sinn. Wenn Sie einen Zeiger auf int dereferenziert haben und ein Objekt vom Typ Apple erhalten haben, wäre das sehr merkwürdig.

GameObject * (a Zeiger zu GameObject) bedeutet, daß es einige Teil des Speichers besteht, dass dieser Zeiger zeigt auf, und diese Speicher sollte GameObject als ein Objekt des Typs behandelt werden. Wenn Sie einen Zeiger dereferenzieren, erhalten Sie tatsächlich Zugriff auf diesen Speicher, der offensichtlich als GameObject behandelt wird.

+0

aber die OP besagt, dass Objekte durch verschiedene abgeleitete Klassen zugewiesen werden, können Sie mehr erklären? –

+0

Es spielt keine Rolle, wie die Objekte erstellt werden. Es kommt nur darauf an, dass sie über das 'GameObject'-Interface aufgerufen werden, daher verhalten sie sich wie' GameObject'. – 0x5453

+0

@LorenceHernandez, es spielt keine Rolle: Sie dereferenzieren einen Zeiger auf 'GameObject' und Sie erhalten ein Objekt vom Typ' GameObject'. – ForceBru

0

foo() Überladung wird während der Programmkompilierung ausgewählt. Und der Compiler hat offensichtlich keine Ahnung, was die wirklichen Arten von Objekten sind, die Sie in Ihren Schleifen passieren, also wählt er das einzige, was es sicher weiß.

Es gibt verschiedene Möglichkeiten zur Lösung dieses Problems im Allgemeinen, Google "Double Dispatch" oder "Besucher Muster".

Verwandte Themen