this-Pointer aus Oberklasse



  • @MatheStein
    C++ ist statisch typisiert.



  • Mal abgesehen von der Frage, warum du nicht nur eine x-Variable nimmst: Du kannst auch einem virtuelle GetX() und SetX()-Funktion schreiben, statt foo() virtuell zu machen.



  • Man kann es auch mit CRTP lösen. Vorher sollte man aber nochmal rekapitulieren, ob es im konkreten Fall nicht bessere Lösungen gibt.



  • ipsec schrieb:

    Man kann es auch mit CRTP lösen. Vorher sollte man aber nochmal rekapitulieren, ob es im konkreten Fall nicht bessere Lösungen gibt.

    👍



  • ipsec schrieb:

    Man kann es auch mit CRTP lösen.

    Könntest du das mal kurz andeutungsweise demonstrieren? So einen Gedanken hatte ich auch, aber hab keinen Ansatz gefunden.



  • Ich werde jetzt wahrscheinlich Meilenweit vorbeischießen, aber es sieht so offensichtlich aus:

    template<typename fooT>
    class A
    {
      public:
    
        A() {x = 1;}
    
        fooT* foo()
        {
          return dynamic_cast<fooT*>(this);
        }
    
        int x;
    
    };
    
    class B : public A<B>
    {
      public:
    
        B() {x = 2;}
    
        B* foo()
        {
          return this;
        }
    
        int x;
    };
    

    Wenn das die Antwort wäre: Schade, dass static_assert/enable_if nicht gehen.



  • Bei CRTP verwendet man üblicherweise static_cast.

    Ansonsten... möglicherweise ist es das was der OP will. Es ist allerdings strenggenommen nicht das wonach er gefragt hat - schliesslich gibt es dabei keine Klasse "A" mehr, nur mehr eine Klasse "A<B>". Wenn wir dann C von B ableiten sind wir wieder wo wir angefangen haben.



  • Ja, das ist nicht ganz das, was ich mir vorgestellt hatte. Das foo in B ist wahrscheinlich nur ein Flüchtigkeitsfehler, aber dass A jetzt mit der konkreten Subklasse parametrisiert wird ... wenn dann muss foo ein Funktionstemplate sein. Und das geht halt nicht, weil man das implizite Argument nicht "zu fassen" kriegt.



  • Achja, man könnte das ganze natürlich auch gleich so machen...

    class A 
    { 
    public: 
        A() { x_ = 1; }
    
        virtual int& x() { return x_; } 
    
        int x_;
    }; 
    
    class B : public A 
    { 
    public: 
    
        B() { x_ = 2; }
    
        virtual int& x() { return x_; } 
    
        int x_;
    }; 
    
    int main() 
    { 
       B b; 
       cout << b.x() << endl; 
    
       return 0; 
    }
    


  • Man kann eine Menge machen, wenn man nicht weiß, welches Problem der OP eigentlich genau lösen will. Man kann aufgrund des abseitigen Designs auch nicht die üblichen Standardrandbedingungen annehmen. Von dem was er schreibt gehört zu den Randbedingungen aber: Die Methode darf nicht in der abgeleiteten Klasse redefiniert werden.

    Meine Überlegung war folgendermaßen: Wäre foo eine freie Funktion(stemplate), dann könnte man es so machen:

    template<class T>
    T* foo(T& t) {
      return &t;
    }
    
    B b;
    foo(b)->x
    

    Soweit, so trivial. Geht das ganze auch als Memberfunktion? Nein, obwohl bei nichtvirtuellen Memberfunktionen b.foo() im Grunde nichts anderes als foo(&b) ist, da der Typ, mit dem das Template parametrisiert ist, der Typ des impliziten this-Arguments und damit nicht (syntaktisch) zugänglich ist.

    class A { ...
    template<class T>
    T* foo(/* T* this ??? */)
    {
      return static_cast<T*>(this);
    }
    

    Irgendwie widerspricht das meinem Schönheitsempfinden 🙂


Anmelden zum Antworten