"virtuelle" Vergleichsoperatoren



  • Ich habe Instanzen verschiedener Klassen zu vergleichen , über Pointer zu der Basisklasse ( Container mit Pointern )

    Was haben wir

    class Base
    {
    public:
        bool operator == (Base const &) const {
            std::cout << "Base::operator ==\n";
            return true;
       }
    };
    
    class Derived:public Base
    {
    public:
        bool operator == (Derived const &) const {
            std::cout << "Derived::operator ==\n";
            return true;}
    };
    
    Base * b1 = new Derived(),*b2 = new Derived();
    *b1==*b2; // führt Base::operator== aus , weil nicht virtuell
    

    Dann habe ich folgende Lösung "erfunden" , jetzt was ich nicht
    ob ich das Rad neu erfinde und es gibt schon eine Musterlösung 😕

    class Base
    {
    public:
        virtual bool eq(Base const & b) const {
            std::cout<<"Base\n";
            return true;
            }
    };
    
    class Derived:public Base
    {
    public:
        bool eq(Base const & b) const {
            const Derived d=dynamic_cast<const Derived&>(b);
            std::cout<<"Derived\n";
            return true;
            }
    };
    
    bool operator == (Base const & lhs,Base const & rhs)
    {
        return lhs.eq(rhs);
    }
    


  • In deinem Beispiel führt b1==2 gar nichts aus, weil du Pointer vergleichst. In diesem Fall bringt dir virtual auch recht wenig, da du das Objekt als Base ansprichst und der Compiler nicht sieht, dass die Funktion im eigentlichen Objekt überschrieben ist.



  • devkid schrieb:

    In deinem Beispiel führt b1==2 gar nichts aus, weil du Pointer vergleichst. In diesem Fall bringt dir virtual auch recht wenig, da du das Objekt als Base ansprichst und der Compiler nicht sieht, dass die Funktion im eigentlichen Objekt überschrieben ist.

    Ja , das ist ein Syntaxfehler

    *b1==*b2
    


  • Diese Lösung ist besser

    class Base
    {
    public:
        bool operator == (Base const & b) const { return eq(b); }
    protected:
        virtual bool eq(Base const & b) const { std::cout<<"Base\n"; return true; }
    };
    
    class Derived:public Base
    {
    protected:
        bool eq(Base const & b) const {
            assert( typeid(b)==typeid(*this) );
            const Derived d=dynamic_cast<const Derived&>(b);
            std::cout<<"Derived\n";
            return true;
            }
    };
    
    int main(int argc,char** argv)
    {
        Base* d1=new Derived();
        Base* d2=new Derived();
        *d1==*d2;
    }
    

    So kann man Objekte nur gleichen Typs vergleichen



  • Vorsicht, es kann bei virtuellen Vergleichsoperatoren passieren, dass z.B. A==B ist, aber B==A falsch. Was ja eher unlogisch ist.


Anmelden zum Antworten