Static-Methode in abstrakter Basisklasse



  • Hallo!

    Ich möchte eine abstrakte Basisklasse erstellen, die dann andere Klassen, die davon erben, dazu zwingen soll bestimmte Methoden zu implementieren.

    Jetzt kommt's: Ich will die erbenden Klassen irgendwie dazu zwingen eine bestimmte static Methode zu implementieren. Ich weiß aber nicht wie die Syntax dafür aussieht? static und virtual beisst sich laut Compiler.

    Geht das überhaupt?



  • Nope geht nicht, da Du beim aufrufen statischer Funktionen kein polymorphes Objekt haben musst sondern die gewünschte Klasse direkt adressieren kannst. Welchen Pfad in der Hierarchie sollte der Compiler dann verfolgen, wenn du AbstractClass::StaticMethod() aufrufst.



  • LordJaxom schrieb:

    Nope geht nicht, da Du beim aufrufen statischer Funktionen kein polymorphes Objekt haben musst sondern die gewünschte Klasse direkt adressieren kannst. Welchen Pfad in der Hierarchie sollte der Compiler dann verfolgen, wenn du AbstractClass::StaticMethod() aufrufst.

    aber die ist ja virtual, also sowas wie

    AbstractClass::VirtualStaticMethod()

    Sprich die abstrakte basisklasse hat diese static methode nicht, aber die davon erbenden müssen sie implementieren



  • Nein, geht wirklich nicht. Schon gar nicht, wenn Base die Methode foo nicht hat, aber Derive foo implementieren muss.

    Edit: virtual und static in der Kombo bringt's echt nicht.

    MfG

    GPC



  • Bei einer virtuellen Methode wird anhand der vtable ermittelt welchen Typ das verwendete Objekt (*this) tatsächlich hat und die "richtige" Methode dazu ausgewählt. Eine statische Methode hat keinen this-Zeiger - also woher soll die bitteschön wissen, welche Klassenmethode jetzt verwendet werden soll?
    (denk mal drüber nach)



  • hmmm4546 schrieb:

    aber die ist ja virtual, also sowas wie

    AbstractClass::VirtualStaticMethod()

    Sprich die abstrakte basisklasse hat diese static methode nicht, aber die davon erbenden müssen sie implementieren

    Damit widersprichst Du Dir selbst - Du addressierst direkt die Klasse AbstractClass und erwartest vom Compiler eine der Ableitungen (BTW, welche bitte?) zu suchen.



  • was hättest du davon, wenn eine methode virtual ist, obwohl sie nicht von einem objekt abhängt?
    was stellst du dir vor, soll mit den statischen methoden der subklassen passieren, wenn du die statische methode der basisklasse aufrufst?
    soll per zufall irgendeine subklasse gewählt werden und deren statische methode aufgerufen werden?
    sollen die statischen methoden aller subklassen aufgerufen werden?



  • Ich glaube er meint folgendes:

    #include <iostream>
    
    struct A {
        static void F() { std::cout << "A" << std::endl; }
    };
    
    struct B : public A {
        static void F() { std::cout << "B" << std::endl; }
    };
    
    int main() {
        A a;
        a.F();
        B b;
        b.F();
        A* p = new A;
        p->F();
        delete p;
        p = new B;
        p->F();
        delete p;
    }
    

    Würde static und virtual gehen, dann käme B beim letzten Aufruf herraus, doch überleg dir was der Kompiler machen muss: Er muss schauen welcher Typ sich hinter dem Zeiger versteckt, wenn die virtuelle Funktion aufgerufen wird, und wenn er das macht, ist der Vorteil von static schon fast weg, allerdings auch nur fast.

    Also eigentlich müsste es doch möglich sein static und virtual zusammen zu benutzen, und es würde doch auch Sinn ergeben, oder? Ich meine jetzt: Sind static-Methoden nicht nen kleinen Tick schneller, da sie keinen Zeiger auf ihre Instanz erhalten? Oder ist das egal?

    mfg.



  • Was er meint ist schon klar 😉 aber in diesem Fall macht der Compiler aus p->F() ein A::F(), weil ihn das Objekt überhaupt nicht interessiert. Da eine statische Funktion kein this-Argument hat, braucht der Compiler das Objekt nur, um die Klasse zu ermitteln (und der Zeiger p ist nunmal vom Typ A).

    Wäre o.a. möglich, würde nicht nur der Compiler mehr zu tun haben, er müsste hier (und nur hier!) auch protestieren wenn A::F() direkt angesprochen wird, denn wo sucht er jetzt die Virtualität? Implizit garnicht würde mir nicht wirklich sonderlich gut gefallen 😉


  • Mod

    joomoo schrieb:

    Also eigentlich müsste es doch möglich sein static und virtual zusammen zu benutzen, und es würde doch auch Sinn ergeben, oder? Ich meine jetzt: Sind static-Methoden nicht nen kleinen Tick schneller, da sie keinen Zeiger auf ihre Instanz erhalten? Oder ist das egal?

    mfg.

    das geschwindigkeits-'problem' bei virtuellen funktionen besteht primär in dem indirektenaufruf, der die sprungvorhersage heutiger prozessoren verhindert (mittels profiling informationen hat der compiler hier allerdings verschiedene möglichkeiten, das zu umgehen, gleichfalls bei JIT compilern oder selbstmodifizierendem code). evtl. ist etwas pseudo-virtuelles in der art gesucht:

    #include <iostream>
    
    struct A {
        A() : f(&A::f_) {}
        void (*f)();
    private:
        static void f_() { std::cout << "A" << std::endl; }
    };
    
    struct B : public A {
        B() { f = &B::f_; }
    private:
        static void f_() { std::cout << "B" << std::endl; }
    };
    
    int main() {
        A a;
        a.F();
        B b;
        b.F();
        A* p = new A;
        p->f();
        delete p;
        p = new B;
        p->f();
        delete p;
    }
    

    alternativ könnte man einen container benutzen, der die zuordnung zwischen typeinfo und zeiger bewirkt und so den zusätzlichen zeiger in jeder instanz vermeiden. im prinzip aber trotzdem sinnlos, eine virtuelle const memberfunktion ist genauso nützlich.


Anmelden zum Antworten