Methodenaufruf mit variablem Methodennamen



  • Hallo,

    ich habe verschiedene Formulare, auf denen Edit, LabledEdit, usw. -Komponenten implementiert sind. Diese besitzen alle ein OnExit-Ereignis, in dem ich den Inhalt auf die Einhaltung vorgegebener Grenzen überprüfe. Jedes Feld hat dabei unterschiedliche Grenzen, mal als int und mal als double.
    Ich möchte das Formular an eine Methode übergeben, die von jeder Eingabekomponente das OnExit()-Ereignis aufruft.
    Sollte es einmal kein OnExit-Ereignis für eine Komponente geben, sollte das die Methode nicht weiter stören...also keine Exception auftreten.

    Hier mein bisher erstellter Methodenteil:

    void TMethoden::ExitFunktionenAusfuehren(TForm *Formular)
    {
    	TComponent *Komponente;
    
    	try
    	{
    		for (int i = 0; i < Formular->ComponentCount; i++)
    		{
    			Komponente = Formular->Components[i];
    			AnsiString ASKlassenname = Komponente->ClassName();
    			if (ASKlassenname == "TEdit" || ASKlassenname == "TLabeledEdit" || ASKlassenname == "TComboBox")
    			{
    				AnsiString ASMethodenname = Komponente->Name;
    				ASMethodenname += ASMethodenname + "Exit(TObject *Sender)";
    				/* jetzt die Methode "ASMethodenname", wenn vorhanden aufrufen */
    			}
    		}
    	}
    	__finally
    	{
    		delete Komponente;
    	}
    

    Wie kann ich die Methode zur Laufzeit aufrufen, wenn ich deren Namen zur Entwicklungszeit noch nicht kenne?



  • Hallo

    So geht das nicht, Methoden haben in C/C++ zur Laufzeit keine Namen mehr, nur noch Speicheradressen (genauso wie Variablen).
    Du kannst aber mit den Speicheradressen arbeiten :

    // Deklaration des Formes
    #include <map> // Für std::map
    
    class Form...
    {
      ...
      // Sammlung der Exit-Methoden, indiziert nach Name
      std::map<String, TNotifyEvent> m_exits; 
    }
    
    // Implementation des Form-Konstruktors
    void __fastcall Form::Form()
    {
      // Die im Form vorhandene Methode ExitA wird in die Map eingetragen
      m_exists.insert(std::make_pair("ExitA", ExitA));
    }
    
    ...
    // Anhand des Names die Methode aus der Map suchen :
    String name = ...;
    std::map<String, TNotifyEvent>::iterator it = m_exists.find(name);
    if (it == m_exists.end())
    {
      // Name nicht gefunden!
    }
    else
    {
      // Gefundene Methode zuweisen
      Komponente->OnExit = it->second;
    }
    

    bis bald
    akari



  • Was soll das try/catch/finally Konstrukt mit delete? ich kann keinen Sinn dahinter erkennen.



  • @DocShoe

    Das try... finally habe ich implementiert, um den allokierten Speicher für "Komponente" sicher wieder freizugeben. Sonst besteht die Gefahr eines Speicherlecks, wenn aus irgendeinem Grund ein Fehler auftritt.



  • Aber du hast doch gar keinen Speicher (mit new) reserviert!!!



  • Ahja, richtig...das erklärt die Frage 🙂



  • Nur das du nichts freigeben musst weil du nichts alloziert hast. Du hast hier also kein Speicherleck eher löscht du etwas zuviel.
    [edit]Merke: nicht telefonieren und dann abschicken. 🙂 [edit]


Log in to reply