Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Array von Funktionen???

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
22.01.2006, 21:12 Uhr
Karldin Shinowa
Professional Noob


Hi hab ne Frage. Ich bin noch net sehr gut in C++ und schreibe deshalb an einem Textadventure...
Es soll ca so wie in den Bücher ablaufen nur halt musst nichts mehr aufschreiben und so.
die verschiedenen Teile des games sind punkte und da ist schon mein problem. Hier mal wie meine Mainloop ausschauen soll:


C++:
while(gameover==false){

//Aufruf eines menüs wo man einblicke in inventar und anderes hat
Spieler.Menue();/*Spieler=Klasse; da ich alles vom spieler in ner klasse hat muss es ne elementfunktion sein*/

//Sprung zum nächsten Punkt
Punkte(Next);

}



und hier zur Funktion Punkte:

C++:
int Punkte(int Next){
switch(Next){
case 1:Punkt1();break;
case 2:Punkt2();break;
.
.
.
}



Dieser switch isn bissi dumm. es muss doch einfacher gehen. da kam ich auf die idee vllt gibt es ja ne möglichkeit dass ich das direkt so mache als hätte ich ein array aus funktionen
so ca.


C++:
Punkte()[Next];



wenns so was net gibt auch gut. trotzdem sind andere verbesserungs- (vereinfacherungs-) vorschläge willkommen

mfg Karldin
--
Ich will die Welt verbessern, doch Gott gibt mir nicht den Code.

Dieser Post wurde am 22.01.2006 um 21:13 Uhr von Karldin Shinowa editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
22.01.2006, 22:09 Uhr
0xdeadbeef
Gott
(Operator)


Jupp, das geht. Die Syntax dafür ist aber etwas widerlich - mit nem typedef ist es halbwegs lesbar:

C++:
#include <iostream>

void foo() { std::cout << "foo" << std::endl; }
void bar() { std::cout << "bar" << std::endl; }

typedef void (*procedure)(); // <-- der widerliche Teil

void call_proc(int index) {
  static procedure procs[] = { foo, bar };

  procs[index]();
}

int main() {
  for(int i = 0; i < 2; ++i) {
    call_proc(i);
  }
}


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 22.01.2006 um 22:10 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
23.01.2006, 08:15 Uhr
Karldin Shinowa
Professional Noob


widerlich ist schön ausgedrückt^^
ich versteh net genau was procedure is sonst kapier ichs ca.
hier nochmal meine Schleife. Hab ich das hier jetzt richtig verwendet?

C++:
int Next=1;
void Punkt1()
{
cout<<"point1";
}

void Punkt2(){
cout<<"point2";
}

typedef void (*procedure)();

void Punkte(int index) {
  static procedure procs[] = { Punkt1, Punkt2 };
  procs[index]();
}

int main() {
   while(gameover==false)
   {  
   //Zeile1-siehe unten
      Spieler.Menue();  
      Punkte(Next);
      getchar();
   }
}



das einzige was mir auffält is das er wenn ich Next=1 habe den 2.Punkt verwendet. Das könnte ich leicht beheben wenn ich bei Zeile1 ein Next-- einfüge.
Da ich aber das Ganze auch verstehen will und denke dass ich sonst noch probs mit dem code bekomme wäre ich erfreut wenn mir einer den code(besonders procedure) erklären könnte. vllt finde ich ja dann sogar selber nen weg ohne Next--
achja nur so:ich weiß wie arrays funktionen zeiger und das ganze funktionieren also braucht ihr nicht erklären: schau das ist ein funktionsaufruf....

thx auf jeden fall
--
Ich will die Welt verbessern, doch Gott gibt mir nicht den Code.

Dieser Post wurde am 23.01.2006 um 08:16 Uhr von Karldin Shinowa editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
23.01.2006, 09:54 Uhr
0xdeadbeef
Gott
(Operator)


typedef erzeugt ein Alias für Typnamen. Zum Beispiel

C++:
typedef int ganzzahl;

ganzzahl x;


Für Funktionspointer ist die Syntax allerdings bösartiger, einen Funktionspointer würdest du zum Beispiel mit

C++:
void foo() { ... }

// ...

void (*bar)() = foo;
bar();


erstellen. Noch widerlicher sieht das bei Arrays aus:

C++:
void (*bar[])() = { foo, foo };


Deswegen benutzt man an der Stelle sinnigerweise ein typedef. (Du solltest mal sehen, wie das aussieht, wenn man Funktionspointer als Funktionsparameter übergibt... *schauder*) Und das sieht nun mal so aus:

C++:
void foo() { ... }

typedef void (*procedure)();

// ...

procedure bar = foo;
bar();


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
23.01.2006, 16:08 Uhr
RHBaum



Fuer kleinere ueberschaubarere Projekte mag die Loesung mit raw Funktionspointer durchaus ok sein. Fuer groessere Projekte insbesondere wenn die Verhaeltnisse noch bisserl komplizierter werden, versucht man das in C++ dann doch eher objektorientiert anzugehen ... und die Funktionspointer durch virtuelle funktionen (welche auch durch funktionspointer intern realisiert sind) aufzuloesen ....

Vorgehensweisse waere dann in etwa :

C++:
// Ne Abstracte Command klasse bauen
class ICommand
{
public:
    virtual ~ICommand(){}
    virtual void Execute() = 0;
protected:
    ICommand(){}
};

// fuer jede deine Aktion nen definierte commandklasse erzeugen

class Command1 : public ICommand
{
public:
    // hier die Execute Methode dfuer die klasse definieren
    virtual void Execute()
    {
         // tun was zu tun ist ....
    }
};

// fuer deine COmmandos nen Array oder ne Map anlegen ....
ICommand * mCommands[5];

// commandos mit zeigern befuellen
mCommand[0] = new Command0;
mCommand[1] = new Command1;
....

// zugriff geht dann relativ unkompliziert ....
mCommands[index]->Execute();



Macht eigentlich nich viel mehr und anders als wie die funktionspointer geschichte .... ausser das es wesentlich mehr schreibarbeit ist ....
Dafuer isses aber auch uebersichtlicher -> besser wartbar
Und man ist min dem Command-objekten flexiebler ... weil man ueber die initialisierung nachtraeglich noch parameter einfuehren / abhaengigkeiten definieren kann. Mach das mal mit den Funktionspointern ^^

Ob dir der Aufwand das wert ist, musst selbst entscheiden ... wie gesagt bei kleineren Projekten sind funktionspointer meist ok, weil derMehraufwand fuers tippern doch nich zu unnerschaetzen ist ....

Ciao ...

Dieser Post wurde am 23.01.2006 um 16:13 Uhr von RHBaum editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
23.01.2006, 16:34 Uhr
Karldin Shinowa
Professional Noob



die 2. variante versteh ich noch weniger als die erste. obwohl die erste versteh ich auf jeden fall genügend um sie anzuwenden
--
Ich will die Welt verbessern, doch Gott gibt mir nicht den Code.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
23.01.2006, 17:05 Uhr
Pablo
Supertux
(Operator)



Zitat von Karldin Shinowa:

die 2. variante versteh ich noch weniger als die erste


musst du auch nicht, vor allem wenn dein projekt kein C++ Projekt ist
--
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
23.01.2006, 17:07 Uhr
0xdeadbeef
Gott
(Operator)


RHBaum: C++ ist nicht nur objektorientiert, was den Ansatz oben ziemlich überflüssig macht. Wo Funktionspointer nicht ausreichen, empfiehlt es sich zumindest, sich an gängige Aufrufskonventionen zu halten um seine Funktoren auch in z.B. STL-Algorithmen verwenden zu können, das bedeutet in diesem Fall insbesondere die Überladung des Klammeroperators. Zum Beispiel:

C++:
#include <iostream>

class counter {
public:
  counter(int x = 0) : x_(x) { }
  int operator()() { return x_++; }

private:
  int x_;
};

int main() {
  counter cnt(5);

  for(int i = 0; i < 10; ++i) {
    std::cout << cnt() << std::endl;
  }
}


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
23.01.2006, 17:29 Uhr
(un)wissender
Niveauwart


Wieso ist RHBaum Ansatz überflüssig? Ist halt eine andere Methode.
--
Wer früher stirbt ist länger tot.
 
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: