Vererbung



  • Guten,

    habe mal wieder ein Problem - ich glaube (hoffe) dass die Lösung auf der Hand liegt aber ich komme nicht drauf 😞

    Problem: Ich habe zwei Klassen (foo & bar). Diese haben (fast) identische - statische und nicht statische - Funktionen; viele benöten Konstanten und gerade diese sind für foo und bar unterschiedlich.
    Also zB.:

    class foo
    {
    public:
      static void func1(int blah);
      void func1();
    }
    void foo::func1(int blah)
    {
      // mache etwas mit MY_CONST = 5
    }
    void foo::func1()
    {
      // mache etwas mit MY_CONST = 5
    }
    
    class bar
    {
    public:
      static void func1(int blah);
      void func1();
    }
    void bar::func1(int blah)
    {
      // mache etwas mit MY_CONST = 9
    }
    void bar::func1()
    {
      // mache etwas mit MY_CONST = 9
    }
    

    Das Problem ist jetzt dass ich gerne die Funktionen von foo an bar vererben möchte (was ja auch Sinn macht). Aber die Funktionen sollen dann andere Werte nutzen. Nun kann ich diese Werte leider nicht einfach als nicht-statische member festhalten (und dann mit Konstruktor beschreiben) da die statischen Funktionen da ja nicht drauf zugreifen können. Als statische member kann ich das ganze auch nicht festhalten weil die vererbten Funktionen ja auf die member von foo und nicht auf die von bar zugreifen. Wie mache ich das also am besten?



  • cooky451 schrieb:

    Problem: Ich habe zwei Klassen (foo & bar). Diese haben (fast) identische - statische und nicht statische - Funktionen; viele benöten Konstanten und gerade diese sind für foo und bar unterschiedlich.

    Eventuell eine Basisklasse, von denen foo und bar erben? Dann könntest du die Konstante dem Konstruktor der Basisklasse übergeben.



  • Nexus schrieb:

    cooky451 schrieb:

    Problem: Ich habe zwei Klassen (foo & bar). Diese haben (fast) identische - statische und nicht statische - Funktionen; viele benöten Konstanten und gerade diese sind für foo und bar unterschiedlich.

    Eventuell eine Basisklasse, von denen foo und bar erben? Dann könntest du die Konstante dem Konstruktor der Basisklasse übergeben.

    Hm.. also das müsste eigentlich funktionieren.
    Manchmal sieht man halt den Wald vor lauter Bäumen nicht 😃 Besten Dank!



  • Ehm.. ne das geht wohl doch nicht -.-
    Die statischen Methoden der Basisklasse können ja trotzdem nicht auf nicht-statische Variablen zugreifen..



  • Ich verstehe nicht, wieso du statische Methoden hast, die auf nicht-statische Attribute zugreifen wollen. Was spricht gegen nicht-statische Methoden? 😉



  • Prinzipiell nichts - wenn ich keine "vernünftige" Lösung finde werden die wohl rausgeschmissen. Allerdings muss man dann zwangsläufig eine Instanz der Klasse erstellen um eine Methode dieser zu nutzen - was an manchen Stellen nicht umbedingt zweckmäßig wäre.



  • Was sind das denn für Methoden? Erklär doch Mal Deinen Kontext.



  • wieso überhaupt klassen?

    int Func(int konstanze)
    {
    	return 1+2+3+konstanze;
    }
    
    int Foo()
    {
    	const int MY_CONST = 5;
    	return Func(MY_CONST);
    }
    
    int Bar()
    {
    	const int MY_CONST = 9;
    	return Func(MY_CONST);
    }
    

    wenn man unbedingt will von mir aus auch mit statischen methoden.



  • Mir ist noch was eingefallen, aber irgendwie macht das alles vermutlich komplizierter als nötig:

    enum ConstSetType
    {
    	SET1,
    	SET2
    };
    
    template<ConstSetType set>
    struct ConstSet
    {
    	static const int c1;
    	static const int c2;
    };
    
    template<>
    struct ConstSet<SET1>
    {
    	static const int c1 = 5;
    	static const int c2 = 10;
    };
    
    template<>
    struct ConstSet<SET2>
    {
    	static const int c1 = 8;
    	static const int c2 = 13;
    };
    
    template<ConstSetType setType = SET1>
    class foo
    {
    protected:
    	static ConstSet<setType> constants_;
    
    public:
    	virtual void c1() const {std::cout << constants_.c1;}
    	virtual void c2() const {std::cout << constants_.c2;}
    };
    
    class bar : public foo<SET2>
    {
    
    };
    
    // Test
    int main()
    {
    	foo<> x;
    	bar y;
    	x.c1();
    	x.c2();
    	y.c1();
    	y.c2();
    return 0;
    }
    


  • Vielleicht sollten wir auf die genaue Problemstellung warten, bevor wir immer komplexere Ideen haben 😉



  • Gut, nur als Kontext des Kontextes - quasi als Metakontext sollte man wissen dass ich mir der nicht zwangsläufigen Sinnhaftigkeit der ganzen Aktion bewusst bin. Ich mache das nur weil ich mich etwas an C++ gewöhnen möchte und mir nichts wirklich besseres eingefallen ist ;).

    Also ich habe zB. eine Klasse die Funktionen für eine Listbox schachteln. (clear, addstring usw.)
    Diese Funktionen gibts jetzt einmal statisch (hier muss man ein window handle übergeben) und einmal nicht statisch (hier wird das window handle der Instanz genutzt).
    Wenn Du mir jetzt sagst dass ganze ist eh unsinnig es gibt doch die MFC dann hau ich Dich 😃

    Edit: Wow - viele Beitrage in 5 Minuten oO^^



  • Dann ruft die nichtstatische Methode die statische mit seinem Handle auf.



  • Die nicht statische Methode hat kein Handle als Parameter, das ist ja der Sinn 😃



  • Nexus:
    Laufzeitpolymorphie allein klappt halt nicht für statische Methoden und die virtual-Methoden sind nur ein Beispiel. Die können in dem eigentlich auch nicht-virtual sein, ändert ja nichts. Und ja, ich find das auch overengineered, aber mir fällt sonst auch nichts ein, wenn man sein kaum benanntes Design so behalten möchte... 🙂

    cooky:
    Und wieso soll man überhaupt die Möglichkeit haben über ein Window-Handle, was meinem Verständnis auf einer anderen Abstraktionsebene steht, etwas zu erreichen? Wenn du so eine Schicht aufbaust, würde ich dem Anwender auch gar nicht die Möglichkeit geben, dass er die "normalen" Handles benutzen kann, wo ist denn da der Sinn?



  • cooky451 schrieb:

    Die nicht statische Methode hat kein Handle als Parameter, das ist ja der Sinn 😃

    class ListBox
    {
    public:
      static void Clear(Handle liste)
      { /* ..Implementierung.. */ }
    
      void Clear()
      {
        Clear(handle_);
      }
    private:
      Handle handle_;
    };
    


  • Hm.. mir fällt gerade auf dass ich in der statischen Methode einfach eine Temporäre Instanz erstellen und dann die nicht statische Methode aufrufen könnte oO..



  • Welchen Sinn hat das Handle dann?



  • cooky451 schrieb:

    Hm.. mir fällt gerade auf dass ich in der statischen Methode einfach eine Temporäre Instanz erstellen und dann die nicht statische Methode aufrufen könnte oO..

    Was ist denn daran besses als andersrum (so wie eben gezeigt)??



  • @Eisflamme
    Dass man bei öfter genutzten Fenstern auch eine Instanz der Klasse erstellen kann und das Handle nur einmal setzen muss.

    @brotbernd
    Dass man die Konstanten nicht als Parameter übergeben muss.
    (Das was Du gezeigt hattest war quasi die Ausgangssituation)



  • Dass man bei öfter genutzten Fenstern auch eine Instanz der Klasse erstellen kann und das Handle nur einmal setzen muss.

    Ja, aber wenn das Handle offensichtlich unwichtig ist, weil die Funktion auch mit einem temporär erzeugten Handle durchgeführt werden kann, was soll das Ganze dann? 😉


Anmelden zum Antworten