Kindklassen zwingen, eine statische Methode zu implementieren [hat sich erledigt]


  • Mod

    Hallo,

    ich habe ein bestimmtes Interface. Dieses sieht auch vor, dass Klassen, die das Interface implementieren, ein paar bestimmte statische Methoden zur Verfügung stellen sollen. Kann ich die Kindklassen irgendwie dazu zwingen, diese Methoden zu implementieren? Man kann ja nicht static void method()=0; schreiben, daher suche ich eine andere Methode.

    Als motivierendes Beispiel denke ich an sowas:

    class Elementarteilchen{
     /* Jedes Elementarteilchen hat einen Ort und Impuls (ich mache hier im Beispiel klassische Physik).
        Ort und Impuls sind für jedes konkrete Teilchen verschieden */ 
     double position[3]; 
     double momentum[3];    
    
     /* Jedes Elementarteilchen hat eine Ladung, aber die ist für alle Teilchen einer Art gleich */
     static double charge;
    };
    
    class Elektron : public Elementarteilchen{
     // Wie kann ich Elektron dazu zwingen, dass es ein Member charge hat?
    }
    

    edit: Mit etwas Überlegungen zu meinem Design hat sich das Problem quasi erledigt. Auf das Beispiel übertragen ist die Ladung jetzt zwar keine Teilcheneigenschaft mehr wie man es erwarten würde, sondern von den Funktionen die die Ladungen verwenden. Aber ich will ja kein Physikbuch schreiben, sondern ein Computerprogramm.



  • template<typename>
    class Elementarteilchen
    {
    protected:
     /* Jedes Elementarteilchen hat einen Ort und Impuls (ich mache hier im Beispiel klassische Physik).
        Ort und Impuls sind für jedes konkrete Teilchen verschieden */ 
     double position[3]; 
     double momentum[3];    
    
     /* Jedes Elementarteilchen hat eine Ladung, aber die ist für alle Teilchen einer Art gleich */
     static double charge;
    };
    
    class Elektron : private Elementarteilchen<Elektron>
    {
    };
    

    Ich habe dieses System benutzt, als ich bei meiner Garbage Collection verschiedene Sets von verwalteten Zeigern implementiert habe. Jedes Set hat die gleichen statischen Member, die jedoch andere Werte aufweisen. Du kannst wenn nötig auch noch eine Spezialisierung Elementarteilchen<void> in die Hierarchie einbauen... 😉

    MfG



  • Elektron hat ja eine Member charge.. Die ist atm bei dir halt noch privat, aber das spielt ja keine Rolle..
    Oder willst du Memberfunktionen? - Da bin ich bei deinem Beschreib nicht ganz sicher..


  • Mod

    Werde mir die Methode von /rant/ mal angucken. Sieht gut aus, besser jedenfalls als das was ich im edit des ersten Posts vorgeschlagen habe.



  • Ev. sowas?

    template <typename Derived>
    class StaticInterface
    {
        static long requireGetTheValueFunction()
        {
            return Derived::getTheValue();
        }
    };
    
    struct MyClass : public StaticInterface<MyClass>
    {
        static long getTheValue()
        {
            return 3;
        }
    };
    
    int main()
    {
        long theValue = MyClass::getTheValue();
        theValue;
    }
    

  • Mod

    drakon schrieb:

    Elektron hat ja eine Member charge.. Die ist atm bei dir halt noch privat, aber das spielt ja keine Rolle..
    Oder willst du Memberfunktionen? - Da bin ich bei deinem Beschreib nicht ganz sicher..

    Ok, habe das public vergessen.

    Aber wenn ich charge über Elektron ändere, dann ändere ich auch charge für alle anderen Kindklassen, was nicht im Sinne der Erfindung ist. Die Vorschläge von /rant/ und theta beheben dies.


  • Mod

    Ich habe mal ein bisschen rumprobiert, die Vorschläge sind wirklich viel besser, als das was ich mir ausgedacht habe. Für alle die diesen Thread hier später mal lesen, noch eine Beispielimplementierung für einige typische Vererbungsfälle:

    template<typename> class A{
    public:
      static int i;
    };
    
    template<typename T> class B: public A<B<T> >{
    public:
      static int j;
    };
    
    class C: public A<C>{
    };
    
    class D: public B<D>{
      }; 
    
    template<> int A<C>::i=1;       // Geerbten static Member initialisieren, hier von Klasse C
    template<> int B<D>::j=2;       // Siehe Fall 1, aber für Klasse D
    template<> int A<B<D> >::i=3;   // Wie Fall 1, aber doppelt vererbt, für D
    template<> int A<B<int> >::i=4; // Geerbten static Member initialisieren, aber diesmal für Klasse B. int ist ein Dummyparameter
    
    int main(){
       cout << C::i << endl;
       cout << D::j << endl;
       cout << D::i << endl;
       cout << B<int>::i <<endl;
    }
    /* Ausgabe:
    1
    2
    3
    4
    */
    

    Optimal wäre es noch, dass Dummy-int loszuwerden, aber so ist's auch schon schön genug.



  • SeppJ schrieb:

    ... so ist's auch schon schön genug.

    🤡 👍


Anmelden zum Antworten