Operator * überladen



  • hi,

    irgendwie hab ich mit VC++ Express Edition Probleme... Ich mach erstmal ein Beispiel (Die auskommentierten Zeilen sind eigentlich die wichtigen):

    class test
    {
    public:
        test operator * (int i)
        {
            return test();
        };
    };
    
    int main()
    {
        test t;
        // t = 5 * t; //<- Funktioniert nicht, da laut MSVC++ der operator * nicht definiert sei
        // t = t * 5; //<- Funktioniert
    }
    

    Die genau Fehlermeldung bei der ersten auskommentierten Zeile is:
    "no global operator found which takes type 'test' (or there is no acceptable conversion)"
    Die zweite Zeile geht wie gesagt...
    Das Verhalten erscheint mit äußerst komisch, da der Compiler ja eigentlich die Reihenfolge vertauschen kann wie er will, solang ich nicht zwei in der Reihenfolge verschiedene Operatoren definier.

    So, jetzt hab ich mal den operator global gemacht, dann kommt folgende Meldung:
    "error C2678: binary '*' : no operator found which takes a left-hand operand of type 'int' (or there is no acceptable conversion)
    .\main.cpp(17): could be 'test operator *(const test &,int)'
    while trying to match the argument list '(int, test)'"

    Kann man dem Compiler beibiegen (ohne zweimal den gleichen Operator nur mit umgekehrter Operandenreihenfolge zu schreiben), dass der Operator kommutativ ist? Bis jetzt ist mir irgendwie dieses Verhalten nicht untergekommen, deshalb glaub ich, dass es am Compiler liegt...

    Danke für alle Antworten im voraus! 👍



  • class test 
    { 
    public: 
        test operator * (int i) 
        { 
            return test(); 
        }; 
    
        friend test operator * (int i, const test& t)
        {
            return test();
        };
    }; 
    
    int main() 
    { 
        test t; 
        t = 5 * t;
        t = t * 5;
    }
    


  • Danke für die schnelle antwort, aber des is eigentlich genau das, was ich net will: Den gleichen Operator zwei mal nur mit umgekehrter Parameterliste zu schreiben...



  • vielleicht eher so?

    class test 
    { 
    public: 
        test operator * (int i) 
        { //tutwasrechnen();
            return test(); 
        }; 
    
        friend test operator * (int i, const test& t)
        {//tut nur weiterreichen
            return t*i;
        };
    }; 
    
    int main() 
    { 
        test t; 
        t = 5 * t;
        t = t * 5;
    }
    


  • Danke, ich dachts mir eigentlich fast, wollts aber net wahrhaben...

    Mich würd aber denoch interessieren, ob das Beispiel mit den auskommentierten Zeilen zu kompilieren geht oder net.



  • Hi!

    Mit diesem Operator kannst du das Beispiel compilieren.

    friend test operator * (int i, const test& t)
    {//tut nur weiterreichen
        return t*i;
    };
    

    bluecode schrieb:

    aber des is eigentlich genau das, was ich net will: Den gleichen Operator zwei mal nur mit umgekehrter Parameterliste zu schreiben...

    An sowas kommt man eben manchmal nicht vorbei. Außerdem ist es logisch das du mit deiner ersten Version nicht alle Fälle abdecken kannst.

    grüße



  • Du könntest auch nur den globalen Operator verwenden:

    class test
    {
    public:
      test();
      test(int val);
      ...
    };
    
    test operator*(const test& l,const test&r)
    {
      //rechne irgendwas
      return test();
    }
    
    int main()
    {
      test t;
      t=t*5;
      t=5*t;
    }
    

    (der int-Ctor wandelt die 5'en jeweils in ein "test"-Objekt um - und damit solltest du dann umgehen können)

    PS: Ja, ich weiß - mit einem spezialisierten Operator bist du vermutlich etwas schneller.



  • @volkard: Ne ganz andere Frage: Wieso verwendest du bei denem Operator das Schlüsselword friend... Hat das ne spezielle Bedeutung bei Operatoren?

    @CStoll: Des funktioniert in meinem Spezialfall dann leider net (ich hab ja oben nur ein Beispiel zur Verdeutlichung gemacht), da ich aus nem Skalar net einfach nen Vektor machen kann, da Skalarmultiplikation halt was anderes wie Kreuz/Punktprodukt ist.



  • bluecode schrieb:

    @volkard: Ne ganz andere Frage: Wieso verwendest du bei denem Operator das Schlüsselword friend... Hat das ne spezielle Bedeutung bei Operatoren?

    friend ist notwendig, wenn der operator (als globale Funktion steht der außerhalb der Klasse) auf die privaten Member deiner Vektorklasse zugreifen muß. (das geht nicht nur mit Operatoren, sondern mit jeder "fremden" Funktion - und sogar mit kompletten Klassen)

    @CStoll: Des funktioniert in meinem Spezialfall dann leider net (ich hab ja oben nur ein Beispiel zur Verdeutlichung gemacht), da ich aus nem Skalar net einfach nen Vektor machen kann, da Skalarmultiplikation halt was anderes wie Kreuz/Punktprodukt ist.

    Wenn das so ist, bleibt dir doch nur volkards Variante (wobei - da der globale op* nur den Member-Operator aufruft, kann da das friend auch wegfallen):

    class test
    {
    public:
      test operator*(int r);
    };
    
    test operator*(int l,const test& r)
    { return r*l; }
    

Anmelden zum Antworten