geht sowas in c++?


  • Mod

    class Base1 { public: virtual ~Base1() {} };
    

    sonst wie im ersten post. wenn es damit nicht geht, ist dein compiler kaputt.



  • camper schrieb:

    class Base1 { public: virtual ~Base1() {} };
    

    sonst wie im ersten post. wenn es damit nicht geht, ist dein compiler kaputt.

    ich hab jetzt folgenden code in dev-cpp getestet

    #include <iostream>
    #include <stdlib.h>
    
    class Base1 {public: virtual ~Base1() {} };
    class Base2 {};
    
    class A : public Base1 {};
    class B : public Base1, Base2 {};
    
    bool is_derived_from_Base2 (Base1 *x)
    {
        return dynamic_cast<Base2*>(x) != 0;
    }
    
    int main()
    {
        A *a = new A;
        B *b = new B;
    
        bool b1 = is_derived_from_Base2 (a);  // muss false ergeben
        bool b2 = is_derived_from_Base2 (b);  // muss true ergeben
    
        std::cout << b1 << ' ' << b2 << std::endl;
    }
    

    schmeisst bei mir 0 0 raus 😡
    rtti ist doch für gewöhnlich eingeschaltet beim gcc oder?
    (man muss es mit -fno-rtti abschalten wenn man's nicht haben will).



  • du brauchst mindestens eine virtuelle methode.



  • .w schrieb:

    du brauchst mindestens eine virtuelle methode.

    hab ich gerade gemacht

    class Base1 
    {
          public: 
          virtual ~Base1() {} 
          virtual void dummy() {}
    };
    

    ...ändert nix 😞 😞 😞


  • Mod

    class B : public Base1, [b]public[/b] Base2 {};
    


  • Dr. Prof schrieb:

    Alexandrescu hat in modern c++ design sowas gebastelt, musst du mal in seiner loki-lib (gibts auf sourceforge.net) suchen

    Das war aber iirc die Compiletime Variante, für die der eigentliche Typ schon bekannt sein muss.

    So klappts:

    #include <iostream>
    
    #include <FerrisLoki/TypeManip.h>
    
    using namespace Loki;
    
    class Base1 {};
    class Base2 { public: virtual ~Base2 () {} };
    
    class A : public Base1 {};
    class B : public Base1, public Base2 {};
    
    template <typename T, typename U>
    bool is_derived_from_impl (U* x, Int2Type<0>)
    {
        return false;
    }
    
    template <typename T, typename U>
    bool is_derived_from_impl (U* x, Int2Type<1>)
    {
        return dynamic_cast<T*> (x) != 0;
    }
    
    template <typename T, typename U>
    bool is_derived_from (U* x)
    {
        return is_derived_from_impl<T> (x, Int2Type<SuperSubclass<T, U>::value ? 1 : 0> ());
    }
    
    int main()
    {
        A* a = new A;
        B* b = new B;
    
        std::cout << is_derived_from<Base2> (a) << std::endl;  // muss false ergeben
        std::cout << is_derived_from<Base2> (b) << std::endl;  // muss true ergeben
    }
    

    /edit: Sorry, hatte campers Post nicht gesehen. Aber zumindest bei mir war der Rest der Änderungen auch nötig.


  • Mod

    allerdinsg ist

    Base1* c = new B;
        std::cout << is_derived_from<Base2> (c) << std::endl;  // ergibt false
    

    mit deiner variante, filmor. es ging ja gerade darum, einen cross-casts durchzuführen. im übrigen würde ich hier boosts is_convertible benutzen - ist schließlich das, was wir irgendwann im standard sehen werden.



  • Stimmt, aber ohne den Code oben hats bei mir nicht kompiliert. Loki hab ich nur verwendet, um auf Dr. Prof's Post näher einzugehen.


  • Mod

    .filmor schrieb:

    Stimmt, aber ohne den Code oben hats bei mir nicht kompiliert.

    Base1 ist bei dir auch nicht polymorph. das argument muss polymorph sein, nicht der zieltyp.



  • Autsch ... 😞



  • camper schrieb:

    class B : public Base1, [b]public[/b] Base2 {};
    

    hey, danke, das war's 🙂
    sorry, aber ich bin c-freak. bei c++ fehlt mir einfach die praxis...


Anmelden zum Antworten