3 schnell zu beantwortende fragen (*.exe, typnamen(), goto vermeiden)



  • Hey ich hab ma 3 kurze Fragen
    1)
    Wie kriegt man während der Laufzeit heraus wie von meinem Programm der Dateiname der "*.exe" ist

    Ich brauch einen Befehl, wie sizeof welcher jedoch statt der Größe der Variable den Typnamen zurückgibt.
    z.B.

    int a;
    Typnamen(a) b;	// erstellt eine Variable b vom Typ int
    

    Hinweis: ich werde den Befehl in einem Makro verwenden

    goto soll man ja möglichst vermeiden. Mir fällt aber keine sinnvolle Möglichkeit ein wie man folgenden code umschreiben kann.

    void test()
    {
    	int returnvalue
    
    	returnvalue=a();
    	if (returnvalue==0)
    		return 0;
    	if (returnvalue==-1)
    		goto End_of_test;
    
    	returnvalue=b();
    	if (returnvalue==0)
    		return 0;
    	if (returnvalue==-1)
    		goto End_of_test;
    
    	returnvalue=c();
    	if (returnvalue==0)
    		return 0;
    	if (returnvalue==-1)
    		goto End_of_test;
    
    	/* ... */
    
    	End_of_test:
    	return rufe_eine_funktion_auf();
    }
    


    1. ist Windowsspezifisch, ich glaube die Funktion heißt GetModuleFilename.

    2. gibt es nicht... Was hast du denn vor?

    3. naja, in C++ gibt es exceptions. In deinem beispiel könnte man goto ende; return funktion() auch einfach durch return funktion() ersetzen.



  • das mit dem goto-vermeiden sollte nicht wirklich ein problem darstellen, in deinem konkreten beispiel könntest du sogar einfach die return-anweisung anstatt goto verwenden und ansonsten verschachtelst du halt die if-anweisungen (d.h. nur wenn das eine stimmt, wird das nächste if ausgeführt, die bedingungen musst du in deinem beispiel dann nur negieren)



  • DrGreenthumb schrieb:

    1. naja, in C++ gibt es exceptions.

    Die aber nicht als goto-Ersatz gedacht sind.



  • MaSTaH schrieb:

    DrGreenthumb schrieb:

    1. naja, in C++ gibt es exceptions.

    Die aber nicht als goto-Ersatz gedacht sind.

    Aber zur Fehlerbehandlung. Und diese if-Abfragen sehen für mich nach Fehlerabfragen aus.



  • Janko schrieb:

    Hey ich hab ma 3 kurze Fragen
    1)
    Wie kriegt man während der Laufzeit heraus wie von meinem Programm der Dateiname der "*.exe" ist

    #include <iostream>
    using namespace std;
    int main(int argc, char *argv[])
    {
        cout << "Programmdatei: " << argv[0] << endl;
        return 0;
    }
    

    Ob der Pfad der Programmdatei ebenfalls in argv[0] enthalten ist, hängt allerdings vom Compiler ab...

    Janko schrieb:

    Ich brauch einen Befehl, wie sizeof welcher jedoch statt der Größe der Variable den Typnamen zurückgibt.
    z.B.

    int a;
    Typnamen(a) b;	// erstellt eine Variable b vom Typ int
    

    Hinweis: ich werde den Befehl in einem Makro verwenden

    Evtl. Templates oder abstrakte Klassen mit copy-Funktion verwenden, es kommt aber auf dein konkretes Problem an...



  • Mann mann mann ich wollte den ganzen code so einfach wie möglich halten,
    aber bitte schön, wenn ihr das kompliziert wollt, schreibe ich genau was ich will
    😉

    DrGreenthumb schrieb:

    MaSTaH schrieb:

    DrGreenthumb schrieb:

    1. naja, in C++ gibt es exceptions.

    Die aber nicht als goto-Ersatz gedacht sind.

    Aber zur Fehlerbehandlung. Und diese if-Abfragen sehen für mich nach Fehlerabfragen aus.

    nix Fehlerabfragen
    test ist in Wirklichkeit ne windowproc
    a,b,c etc. sind Klassenfunktion, die je nach Klasse die einzelnen Nachrichten verarbeiten. So verarbeitet meine klasse window die Fensternachrichten, der Statemanager die Tasten usw.
    der typ von returnvalue ist ein eigener enum typ bestehend aus nachricht_abgefangen, nachricht_nicht_identifiziert und nachricht_fuer_diese_nicht_zustaendig
    ist die Nachricht nachricht_nicht_identifiziert oder sind alle Klassenfunktionen durchlaufen worden ohne dass die Nachricht verarbeitet wurde wird sie an Windows weitergeleitet.

    -----------------------
    So und

    int a; 
    Typnamen(a) b;    // erstellt eine Variable b vom Typ int
    

    brauch ich als makro für ne Linked_List, weil ich da keine lust habe den Typ zu übergeben

    Der Code sieht so aus:

    #define MAKRO_ELINKED_LIST_ALLE_OBJEKTE(Objekt_Typ, Objekt_Name, erstes_Objekt) \
    	{\
    		for (Objekt_Typ* Objekt_Name = erstes_Objekt;	Objekt_Name;	Objekt_Name=Objekt_Name->eLinked_List.PNachfolger)\
    		{\
    
    #define MAKRO_ELINKED_LIST_ALLE_OBJEKTE_mit_loeschen_erlaubt(Objekt_Typ, Objekt_Name, erstes_Objekt)\
    	{\
    		Objekt_Typ* Objekt_Nachfolger = erstes_Objekt;\
    		Objekt_Typ* Objekt_Name;\
    		while (Objekt_Nachfolger)\
    		{\
    			Objekt_Name=Objekt_Nachfolger;\
    			Objekt_Nachfolger=Objekt_Nachfolger->eLinked_List.PNachfolger;
    
    #define MAKRO_ELINKED_LIST_ALLE_OBJEKTE_END }}
    
    Beispiel zur Verwendung am Beispiel der Klasse EParticleLinked_List
    
    /*(alles extrem vereinfacht und gekürzt)*/
    class EParticleLinked_List
    {
    public:
    	SVector pos;
    	SVector vel;
    	SVector acc;
    	Update(float dtime);
    
    	ELinked_List<EParticleLinked_List>	eLinked_List;
    	float life;
    };
    
    EParticleLinked_List::Update(float dtime)
    {
    	pos+=acc/2*dtime*dtime+vel*dtime;
    	vel+=acc*dtime;
    
    	life-=dtime;
    	if (life<0)
    		eLinked_List.loeschen();
    }
    
    EParticleLinked_List* firstParticle;
    /* aufgerufen werden die Makros nun so:*/
    void Draw (void)
    {
    	MAKRO_ELINKED_LIST_ALLE_OBJEKTE(EParticleLinked_List, Particle, firstParticle)
    		Particle->pos.Draw_in_OpenGL();
    	MAKRO_ELINKED_LIST_ALLE_OBJEKTE_END
    }
    void Update (void){
    	MAKRO_ELINKED_LIST_ALLE_OBJEKTE_mit_loeschen_erlaubt(EParticleLinked_List, Particle, firstParticle)
    		Particle->Update(Timer.dtime);
    	MAKRO_ELINKED_LIST_ALLE_OBJEKTE_END
    }
    void Deinit (void)
    {
    	MAKRO_ELINKED_LIST_ALLE_OBJEKTE_mit_loeschen_erlaubt(EParticleLinked_List, Particle, firstParticle)
    		Particle->eLinked_List.loeschen();
    	MAKRO_ELINKED_LIST_ALLE_OBJEKTE_END
    }
    

    Hinweis: es kommt vor dass zwischen den Makros mehrere Funktion aufgerufen werden, die auch unterschiedliche Parameteranzahlen haben können, denn sonst könnte man das ja mit einer template Funktion "AlleObjekte" mit einem Klassenfunktionspointer als Parameter machen.
    Das ich Makros verwende resultiert übrigens aus folgendem beitrag:
    http://www.c-plusplus.net/forum/viewtopic.php?p=366554#366554



  • Aber wo du da jetzt goto brauchst verstehe ich nicht.

    Steven schrieb:

    Ob der Pfad der Programmdatei ebenfalls in argv[0] enthalten ist, hängt allerdings vom Compiler ab...

    Nee, was überhaupt in argv[0] drin steht, hängt davon ab wie das Programm aufgerufen wurde.



  • typeof gibts nur experimetellerwise beineinigen vorgreifenden Compilern. Offiziell wirds sowas erst in C++0x geben.

    Wegen des goto-vermeindens also bei deinem Beispiel gibts so viele möglichkeiten, das ist ja schon unfassbar.

    void test() 
    { 
        if (a() || b() || c())
           return 0;
        return rufe_eine_funktion_auf(); 
    }
    

    Ist kürzer und übersichtlicher, macht aber das selbe. Denke an das besondere Verhalten der logischen Operatoren.

    zur verketteten Liste: Was kann deine Liste, was die der STL nicht kann. Die kann sogar dinge, wie splicing, ..., die man sonst fast nirgend findet. Ich kann mir grade keine wichtige Operation auf Listen vortellen, die nicht einfach mit std::list zu implementieren wäre.

    struct draw_internal {
       void operator () (cosnt Particel_type & particel)
       {
          particle->pos.Draw_in_OpenGL();
       }
    }
    
    void Draw (void) 
    { 
        for_each (partikel_liste.begin(), partikel.end(), draw_internal());
    }
    


  • @Helium

    if (a() || b() || c())

    Hmm aber b soll doch nicht aufgerufen werden wenn a=0 oder a=-1. In deinem Beispiel wird b aber trotzdem aufgerufen weil es keine konstante Funktion ist.

    Was kann deine Liste, was die der STL nicht kann

    Okay da könnte es was geben:
    1)
    Warum codet man eigentlich struct/class (wie Vector2D) für ein High End Spiel obwohl es sicherlich sowas schon in Hülle und Fülle gibt. Der Grund ist die Geschwindigkeit. Man kann alle Funktionen auf ein minimum an befehlen reduzieren. Natürlich kann man sich auch schon fertiges nehmen und die sich dann anschauen und evtl. umschreiben aber manchmal ist eben selbstcoden schneller.
    (Es ist möglich das das Argument falsch ist, aber die nächsten werden besser *g*)
    2)
    Um alle Partikel zu zeichnen brauche ich 3 Zeilen. Bei dir sinds 7 (inkl. Aufruf).
    3)
    Meine ELinked_List ist jetzt wo ich mir das Anschaue sehr sehr einfach zu handhaben.

    Einfach
    ELinked_List<Klassenname> eLinked_List;
    in die Klasse einfügen und man kann jederzeit mit einem Befehl
    ein neues Objekt erstellen und in die Linked_List einfügen
    oder ein Objekt aus der Linked_List entfehrnen und das Objekt löschen
    Und bei beiden Befehlen brauch man nur einen Pointer eines/des Objekts zu kennen.
    <<----
    Ich habe noch nie Code gefunden (zugegeben ich hab auch noch nie gesucht), wo auch im Objekt selber ein Befehl aufgerufen werden konnte, der da heißt lösche mich selbst und nimm mich aus der Linked List raus.

    EParticleLinked_List::Update(float dtime) 
    { (...)
        if (life<0) 
            eLinked_List.loeschen(); 
    }
    

    Und diesen Befehl mußte man noch nicht mal selbst erstellen, dass macht alles die ELinked_List


Anmelden zum Antworten