Parameter vs. Member Variablen bei Funktionen



  • Was ist generell besserer Stil beim Aufruf von Funktionen,
    Benutzung von Parametern oder Benutzung von Membervariablen?

    Ich habe gelesen, dass Parameter Funktionen schwer greifbarer machen
    und man daher Argumente in Membervariablen umwandeln sollte.

    Die Nutzung von Membervariablen scheint mir aber undurchsichtiger zu sein.
    Zudem sieht man so schlechter, wo überall die Membervariablen verändert werden.
    Meinungen?

    Danke für die Hilfe.


  • Mod

    Membervariablen und Parameter sind Konzepte, die nicht direkt miteinander zu tun haben. Man kann nicht einfach Parameter zu Membervariablen machen, noch umgekehrt¹. Die beiden sind für gänzlich verschiedene Dinge da. Member beschreiben den Zustand eines Dings. Memberfunktionen sind Handlungen, die so ein Ding als Subjekt haben. Die Parameter der Funktion sind Objekte dieser Handlung.

    Die gefürchtete Autoanalogie: Das blaue Auto fährt auf der Straße.
    Du fragst nun, ob es nicht sinnvoller wäre zu sagen:
    a) Das (Blau Straße Auto) fährt.
    oder
    b) Fahren mit Blau und Auto und Straße.
    Und die Antwort ist halt: Weder noch.

    ¹: Klugscheißer werden einwenden, dass es technisch gesehen möglich ist. Trotzdem keine gute Idee.



  • TauCeti schrieb:

    Ich habe gelesen, dass Parameter Funktionen schwer greifbarer machen
    und man daher Argumente in Membervariablen umwandeln sollte.

    Wo?



  • Die Anweisung stammt von Robert Martin. Vielleicht bezieht sich die Anweisung auch hauptsächlich auf Java:

    Parameters make functions harder to grasp and often are on a lower level of abstraction, so avoid them as best you can, e.g. by introducing conceptual helper classes or turning arguments into member variables.



  • TauCeti schrieb:

    Die Anweisung stammt von Robert Martin. Vielleicht bezieht sich die Anweisung auch hauptsächlich auf Java:

    Parameters make functions harder to grasp and often are on a lower level of abstraction, so avoid them as best you can, e.g. by introducing conceptual helper classes or turning arguments into member variables.

    Und hast du das Buch gelesen oder nur The essence of"Clean Code"?



  • TauCeti schrieb:

    Die Anweisung stammt von Robert Martin. Vielleicht bezieht sich die Anweisung auch hauptsächlich auf Java:

    Parameters make functions harder to grasp and often are on a lower level of abstraction, so avoid them as best you can, e.g. by introducing conceptual helper classes or turning arguments into member variables.

    Keine Ahnung wie er es gemeint hat. Man kann das jetzt so oder so auslegen. So wie ich es für total beklopp halten würde oder so wie ich es für vernünftig halten würde. Ich entschliesse mich mal für die 2. Option, und dann käme sowas dabei raus:

    void fun(int fooArg1, int fooArg2, int barArg, int bazArg1, int bazArg2, int bazArg3,int bazArg4, int bazArg5);
    
    // =>
    
    struct FooProperties
    {
       int foo1;
       int foo2;
    };
    
    struct BazSettings
    {
       int baz1;
       int baz2;
       int baz3;
       int baz4;
       int baz5;
    };
    
    void fun(FooProperties fooProps, int barArg, BazSettings bazSettings);
    

    Grundsätzlich würde ich auf jeden Fall sehr davon abraten konzeptuelle Parameter einer Funktion Foo::Bar zu Member-Variablen der Klasse Foo zu machen, nur weil es sonst "unübersichtlich" beim Aufrufen wird oder die Implementierung der Funktion Foo::Bar sonst zu "unübersichtlich" wird.
    Gegen ersteres hilft oft oben gezeigtes, also Gruppierung in structs.

    Und gegen zweiteres hilft oft das Method-Object Pattern. Also ne Hilfsklasse zu machen deren Aufgabe es einzig und alleine ist eine einzige Funktion zu implementieren.
    (Diese Hilfsklasse versteckt man dann idealerweise im .cpp File, z.B. in einem anonymen Namespace.)
    Quasi

    // -----------------------------------------------------
    // fun.h:
    
    int fun(int arg1, int arg2, int arg3, int arg4);
    
    // -----------------------------------------------------
    // fun.cpp:
    
    namespace
    {
    
    class FunMethod
    {
    public:
        static int run(int arg1, int arg2, int arg3, int arg4)
        {
            FunMethod m(arg1, arg2, arg3, arg4);
            return m.run2();
        }
    
    private:
        FunMethod(int arg1, int arg2, int arg3, int arg4)
            : m_arg1(arg1)
            , m_arg2(arg2)
            , m_arg3(arg3)
            , m_arg4(arg4)
        {
        }
    
        int run2()
        {
            // ...
        }
    
        // a zillion helper functions that run2() can call to do its job, and no need to pass all the arguments around every time
    
        int m_arg1;
        int m_arg2;
        int m_arg3;
        int m_arg4;
    };
    
    } // namespace
    
    int fun(int arg1, int arg2, int arg3, int arg4)
    {
        return FunMethod::run(arg1, arg2, arg3, arg4);
    }
    

Anmelden zum Antworten