Präprozessor



  • Hi... ich hab ein bischen Quellcode gefunden und würde diesen nun auch gerne verstehen 🙂 (siehe http://www.codeproject.com/cpp/ratkfactory.asp)

    #define REGISTER_CLASS(factory, class_name, key)				\
    	class_factory_wrapper _register_class_##class_name((factory.register_class((class_name*)0, key), 0));
    

    Eigentlich verstehe ich soweit alles ganz gut... aber die oben gezeigte Zeile bereite mir Kopfschmerzen... kann mir da jemand erklären was dort passiert?

    Es gibt die folgende Klasse

    class class_factory_wrapper
    {
    public:
    	class_factory_wrapper(int) {}
    };
    

    Aber was macht

    _register_class_##class_name((factory.register_class((class_name*)0, key), 0));
    

    Bitte um Erklärung :)... und danke schonmal jetzt für jegliche Hilfe 🙂



  • #define REGISTER_CLASS(factory, class_name, key)                \ 
        class_factory_wrapper _register_class_##class_name((factory.register_class((class_name*)0, key), 0));
    

    das ist eine Makro-Definition

    Steht jetzt im Quelltext

    REGISTER_CLASS(factoryX, class_nameX, keyX)
    

    expandiert der Präprozessor dies zu

    class_factory_wrapper _register_class_class_nameX((factoryX.register_class((class_nameX*)0, keyX), 0));
    

    so bekommt der Compiler es zu sehen.



  • Schonmal danke für die Antwort...

    Aber :)... was macht denn nun

    class_factory_wrapper _register_class_class_nameX((factoryX.register_class((class_nameX*)0, keyX), 0));
    

    ?

    Denn die Klasse

    class class_factory_wrapper
    {
    public:
        class_factory_wrapper(int) {}
    };
    

    Macht ja nicht wirklich was... sie bekommt EINEN int übergeben aber wieso wird aus dem hier ein int

    _register_class_class_nameX((factoryX.register_class((class_nameX*)0, keyX), 0))
    

    Ich versteh das nicht 😞



  • Tja, das ist wirklich trickreich.

    Durch die doppelten Klammern im Konstruktoraufruf werden NICHT zwei Parameter übergeben, sondern es wird der Sequenzoperator benutzt, so daß nur der letzte Wert (0) als Parameter an den Konstruktor übergeben wird.

    Und vorher wird dann die Klasse bei der Factory registriert (bzw. zumindestens der Key).

    Man hätte auch erst die Klasse registrieren können und dann die Variable anlegen können.

    Aber damit dies auch für globale Variablen funktioniert, wurde anscheinend obiger Ansatz gewählt.



  • Danke Th... so ganz verstehe ich das noch nicht... Du schreibst

    im Konstruktoraufruf

    in welchem... das Problem welches ich nicht verstehe ist, dass es keine Methode:

    _register_class_class_nameX
    

    gibt. Woher kommt die? bzw. welche ist das 🙂

    Grüße



  • Das ist keine Methode. Es wird eine Variable mit diesem Namen angelegt.

    Typ Name((funktion(), 0 ));
    

    Es wird eine Variable namens "Name" vom Typ "Typ" angelegt, und zwar mit

    (funktion(), 0)
    

    als Konstruktorparameter. Der Kommaoperator bewirkt hier, dass funktion() aufgerufen wird, der ganze Ausdruck aber hinterher den Wert und Typ von 0 hat.

    Jetzt alles klar?



  • Halleluja... es ist ein Licht aufgegangen :)... DANKE 🙂


Anmelden zum Antworten