Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Double Dispatch

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
15.02.2007, 18:29 Uhr
Tyvan



Hallo ich wollte mal laut englischer Wikipedia unter dem Artikel DOUBLE DISPATCH ein C++ Beispiel programmieren. Doch ich habe hier eigenartige Probleme. Ich programmiere das ganze mit Dev-C++.

Hier erstmal der Code:


C++:
#include <cstdlib>
#include <iostream>

using namespace std;

class SpaceShip
{
public:
       virtual void CollideWith(Asteroid& inAsteroid)
       {
               inAsteroid.CollideWith(*this);        
       }
};

class GiantSpaceShip : public SpaceShip {};

class Asteroid {
public:
  virtual void CollideWith(SpaceShip&) {
    cout << "Asteroid hit a SpaceShip" << endl;
  }
  virtual void CollideWith(GiantSpaceShip&) {
    cout << "Asteroid hit a GiantSpaceShip" << endl;
  }
};

class ExplodingAsteroid : public Asteroid {
public:
  virtual void CollideWith(SpaceShip&) {
    cout << "ExplodingAsteroid hit a SpaceShip" << endl;
  }
  virtual void CollideWith(GiantSpaceShip&) {
    cout << "ExplodingAsteroid hit a GiantSpaceShip" << endl;
  }
};

int main(int argc, char *argv[])
{
    Asteroid theAsteroid;
    SpaceShip theSpaceShip;
    GiantSpaceShip theGiantSpaceShip;
    ExplodingAsteroid theExplodingAsteroid;
    
    Asteroid& theAsteroidReference = theExplodingAsteroid;
    SpaceShip& theSpaceShipReference = theGiantSpaceShip;
    theAsteroid.CollideWith(theSpaceShipReference);
    theAsteroidReference.CollideWith(theSpaceShipReference);
    //-------------------------------------------------------
    //Double Dispatch
    //Now with Double Dispatch
    SpaceShip& theSpaceShipReference2 = theGiantSpaceShip;
    Asteroid& theAsteroidReference2 = theExplodingAsteroid;
    theSpaceShipReference2.CollideWith(theAsteroid);
    theSpaceShipReference2.CollideWith(theAsteroidReference2);
    
    system("PAUSE");
    return EXIT_SUCCESS;
}



Wenn ich das ganze kompiliere dann kommt einfach ein Fehler "variable or field `CollideWith' declared void". Keine Ahnung was das heissen soll.

Das ganze wird aber fehlerfrei kompiliert wenn ich NUR den Code aus der Klasse SpaceShip heraushole, also die Klasse SpaceShip einfach leer bleibt, sonst geht gar nichts. Kann mir mal jemand helfen und mir sagen was hier denn falsch ist? Den Inhalt von main() braucht dazu eigentlich nicht beachten.


Danke und Gruß
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
15.02.2007, 19:05 Uhr
0xdeadbeef
Gott
(Operator)


Forward-Deklaration. Du kannst Asteroid nicht benutzen, bevor du die Klasse definierst.

Außerdem muss GiantSpaceShip seine eigene CollideWith-Methode haben, sonst wird die der Vaterklasse aufgerufen, in der this ein spaceship* ist. So gehts:

C++:
#include<iostream>

class asteroid;

class spaceship {
public:
  virtual void collide_with(asteroid &);
};

class giant_spaceship : public spaceship {
  virtual void collide_with(asteroid &);
};

class asteroid {
public:
  virtual void collide_with(      spaceship &);
  virtual void collide_with(giant_spaceship &);
};

class exploding_asteroid : public asteroid {
public:
  virtual void collide_with(      spaceship &);
  virtual void collide_with(giant_spaceship &);
};

void       spaceship::collide_with(asteroid &a) { a.collide_with(*this); }
void giant_spaceship::collide_with(asteroid &a) { a.collide_with(*this); }

void asteroid::collide_with(      spaceship &s) {
  std::cout << "asteroid hit a spaceship" << std::endl;
}
void asteroid::collide_with(giant_spaceship &s) {
  std::cout << "asteroid hit a giant_spaceship" << std::endl;
}

void exploding_asteroid::collide_with(      spaceship &s) {
  std::cout << "exploding_asteroid hit a spaceship" << std::endl;
}
void exploding_asteroid::collide_with(giant_spaceship &s) {
  std::cout << "exploding_asteroid hit a giant_spaceship" << std::endl;
}

int main() {
        spaceship  s;
  giant_spaceship gs;
            asteroid  a;
  exploding_asteroid ea;

  asteroid  &ar = ea;
  spaceship &sr = gs;

  a .collide_with(sr);
  ar.collide_with(sr);

  /////

  sr.collide_with(a );
  sr.collide_with(ar);
}


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
16.02.2007, 14:20 Uhr
Tyvan



Krass. Ich wusste gar nicht das man einfach "class asteroid;" schreiben kann und danach einfach nochmal mit Inhalt.

Jetzt geht alles. Danke.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
16.02.2007, 17:34 Uhr
stephanw
localhorst



Zitat von Tyvan:
Krass. Ich wusste gar nicht das man einfach "class asteroid;" schreiben kann und danach einfach nochmal mit Inhalt.

Jetzt geht alles. Danke.


Das geht auch nur, wenn Du lediglich Zeiger oder Referenzen auf "asteroid" deklarierst und über diese keine Funktionen aufrufst. Dann braucht der Compiler zum Anlegen einer solchen Zeiger- oder Referenz-Variable nicht die Klassen-Deklaration, denn eine Zeiger-Variable wird immer gleich sein, egal auf welchen Typ sie zeigt. Da, wo Du diese Variable aber benutzt (also z.B. Funktionen aufrufst), brauchst Du die Klassen-Deklaration natürlich, damit der Compiler prüfen kann, was Du damit anstellst.
--
Reden ist Schweigen und Silber ist Gold.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: