[gelöst] Operator (+ und -) mit 2 Parametern überladen



  • Hallo Leute!

    Ich kenne mich nich wirklich mit C++ aus aber schreibe gerade an einem Programm für die Hochschule.

    Jedenfalls würde ich in dem Zuge gerne Operatoren, nämlich + und - mit zwei Parametern überladen. Laut meinem Buch sollte das auch gehen.

    Also ich stelle mir quasi sowas vor:

    CVierpolA operator +(CVierpolA VierpolA1, CVierpolA VierpolA2);
    

    sodass ich dann schreiben kann:

    VierpolA=VierpolA1+VierpolA2
    

    und er aber quasi das hier macht:

    CVierpolA CVierpolA::operator +(CVierpolA VierpolA1, CVierpolA VierpolA2)
    {
    	CVierpolA Merker;
    
    	Merker.Element11 = VierpolA1.readElement11()+VierpolA2.readElement11();
    	Merker.Element11 = VierpolA1.readElement11()+VierpolA2.readElement11();
    	Merker.Element11 = VierpolA1.readElement11()+VierpolA2.readElement11();
    	Merker.Element11 = VierpolA1.readElement11()+VierpolA2.readElement11();
    
    	return Merker;
    
    }
    

    was laut meinem Buch ganz einfach scheint, verursacht bei mir aber diese Fehlermeldung:
    error C2804: Binärer Operator '+' hat zu viele Parameter

    Kann man das doch irgendwie hinkriegen?



  • Ja, Operatoren ausserhalb der Klasse überladen. Zudem Referenzen auf konstante Objekte statt Kopien übergeben.

    VierpolA operator+ (const VierpolA& lhs, const VierpolA& rhs);
    // lhs = left hand side (linker Operand)
    // rhs = right hand side (rechter Operand)
    // (das ist eine übliche Konvention, du kannst die Variablen auch anders nennen)
    

    Üblich ist es, dass der operator+= innerhalb der Klasse überladen und dann vom globalen operator+ aufgerufen wird. Best-Practices und Tipps zur Operatorüberladung findest du in diesem Artikel.

    Übrigens: "C" vor dem Typ "VierpolA" ist unnötig und führt in C++ einige Probleme mit sich, ohne tatsächlichen Mehrwert zu bieten (Argumente gegen UN siehe z.B. hier).



  • Zu allererst mal vielen Dank für die schnelle Antwort.

    So zu der ungarischen Notation... da ist mein Prof ein Fan von, deswegen mach ich die lieber rein.

    Jetzt hab ich deinen Ansatz probiert, bekomme allerdings noch die gleiche Fehlermeldung.

    Fragen die sich mir stellen sind:
    Was verändert das "const"?
    Muss das "&" stehen?
    Und wenn du meinst das Überladen soll ich außerhalb der Klasse machen, meinst du dann, dass ich die Klasse in nem Header erzeuge und aber die Operatoren-Überladungs sache in nem cpp file mache in das ich das Header einfüge? weil wenn ja , dann hab ich das schon so gemacht.

    Sry wenn es sehr komische Fragen sind, aber ich bin wirklich noch Anfänger 😉



  • Lactic_Doug schrieb:

    So zu der ungarischen Notation... da ist mein Prof ein Fan von, deswegen mach ich die lieber rein.

    Okay, aber behalte dir im Hinterkopf, dass es bessere Möglichkeiten gibt... 🙂

    Lactic_Doug schrieb:

    Was verändert das "const"?
    Muss das "&" stehen?

    const gibt Auskunft darüber, ob eine Variable verändert werden darf. Das & bezeichnet eine Referenz. Aber solche Dinge solltet ihr eigentlich lernen, das sind C++-Grundlagen. Und zwar viel grundlegender als beispielsweise Operatorüberladung.

    Lactic_Doug schrieb:

    Und wenn du meinst das Überladen soll ich außerhalb der Klasse machen, meinst du dann, dass ich die Klasse in nem Header erzeuge und aber die Operatoren-Überladungs sache in nem cpp file mache in das ich das Header einfüge?

    Nein, ich meine einfach eine globale Funktion namens operator+ . Also keine Memberfunktion.

    class VierpolA
    {
        // innerhalb der Klasse
    };
    
    // ausserhalb
    VierpolA operator+ (const VierpolA& lhs, const VierpolA& rhs);
    


  • Lactic_Doug schrieb:

    Sry wenn es sehr komische Fragen sind, aber ich bin wirklich noch Anfänger 😉

    Falls du noch kein Buch hast kann ich dir den C++ Primer Plus empfehlen. Ist ein sehr gutes Buch, das einem die Grundlagen sehr gut erklärt. Einfach mal gemütlich durcharbeiten, denn es ist sehr wichtig, dass man die Grundlagen gut versteht.



  • AAAH ok vielen vielen Dank!!
    Jetzt funktioniert es!

    Aber solche Dinge solltet ihr eigentlich lernen, das sind C++-Grundlagen. Und zwar viel grundlegender als beispielsweise Operatorüberladung.

    Jup das stimmt, hatten wir bestimmt auch mal dran, aber der Prof kann meiner Meinung nach kein Wissen vermitteln. Aus den Vorlesungen nehme ich meistens sehr wenig mit. Aber Danke für erklären.

    Super das freut mich jetzt dass das möglich ist.
    Dann werde ich mal weiter programmieren.

    Vielen Dank nochmal!

    @icarus2: danke für den Tip, da werde ich mir das mal besorgen!



  • Muss die dann aber nicht ein friend von VierpolA sein? Zumindest hab ich das so gelernt, das man Operatoren, wenn schon außerhalb, dann als friend o.ä deklariert, damit man dann entsprechend auf die Privaten Funktionen und Typen innerhalb der operator Funktion zugreifen kann oder sollte man das ganze sowieso lieber irgendwie in public Funktionen wrappen?



  • Super dass du es sagst, das Problem hab ich nämlich gerade 😉

    Da will ich auf meine protected Attribute zugreifen, aber das geht dann natürlich nicht, das mit dem als friend machen, ist keine schlechte Idee, das werde ich direkt mal ausprobieren.



  • Lactic_Doug schrieb:

    das mit dem als friend machen, ist keine schlechte Idee, das werde ich direkt mal ausprobieren.

    Doch, das ist eine schlechte Idee. friend solltest du mit Bedacht einsetzen. Da es oft die Kapselung verletzt, ist es nur manchmal dein Freund. 😉

    Wie schon angedeutet kann man das Problem sehr elegant lösen, indem man einen Member-Operator += und einen globalen + anbietet. Es ist ohnehin nur intuitiv, dass die beiden folgenden Ausdrücke kompilieren und semantisch äquivalent sind.

    a = a + b;
    a += b;
    

    Genaueres steht im bereits verlinkten Artikel.



  • Jo das verstehe ich schon, nur ist in meiner Aufgabenstellung ausdrücklich gefordert, dass der Operator + genutzt werden soll. Und das bringt mir auch mehr da so meine Ausgabe später einfacher wird, weil ich ja dann mehrere Vierpole speichern kann die durch Addition in eine Kettenschaltung übergehen.

    Nun würde ich das trotz der Gefahr die Kapselung zu verletzen (was aber meiner Meinung nach in meinem speziellen Fall nicht passieren sollte) aber gerne doch als friend deklarieren.

    Allerdings stoße ich da schonwieder auf Probleme weil da ja nicht außerhalb der Klasse möglich ist.

    Wie kann ich also die Operandenüberladung als friend von VierpolA anlegen? Geht das denn dann überhaupt?



  • Wieder was dazu gelernt 👍

    Wo ich letztens nach solchen Themen gefragt hatte, wurde ich nicht auf dieses wirklich gute Tutorial hingewiesen.

    @Lactic_Doug:
    Doch, mach es als += und dann ruft + einfach nur += auf, egal wie das in der Aufgabenstellung gefordert zu sein scheint, ist dies eine "legale" Lösung des Problems und zeigt das du dich damit auseinander gesetzt hast.

    Ansonsten:

    class VierpolA 
    { 
        // innerhalb der Klasse 
        friend VierpolA operator+ (const VierpolA&, const VierpolA&);
    }; 
    
    // ausserhalb 
    VierpolA operator+ (const VierpolA& lhs, const VierpolA& rhs)
    

    Edit:
    Ist schon traurig, wie viele Dozenten, Professoren, what ever den Standard nicht lehren oder gar beachten, ich weise in der Vorlesung immer wieder den Professor auf diverse Abweichungen zum Standard hin, die dann immer damit abgetan werden mit naja man kann muss aber nicht o.ä. Oder man bekommt keine richtigen Antwort... bei einer Vorlesung hab ich mich 4 mal geäußert und bin dann aufgrund einer eher agressiven Haltung bei der letzten Feststellung, entsprechend ruhig gewesen.....



  • Lactic_Doug schrieb:

    Jo das verstehe ich schon, nur ist in meiner Aufgabenstellung ausdrücklich gefordert, dass der Operator + genutzt werden soll. Und das bringt mir auch mehr da so meine Ausgabe später einfacher wird, weil ich ja dann mehrere Vierpole speichern kann die durch Addition in eine Kettenschaltung übergehen.

    Du stellst eben beide Operatoren zur Verfügung. Operatorüberladung muss intuitiv sein, und ein + ohne zugehöriges += sorgt für Verwirrung.

    Lactic_Doug schrieb:

    Nun würde ich das trotz der Gefahr die Kapselung zu verletzen (was aber meiner Meinung nach in meinem speziellen Fall nicht passieren sollte) aber gerne doch als friend deklarieren.

    Inwiefern ist dein Fall speziell? Der operator+ will auf private / protected -Details zugreifen, was gerechtfertigterweise einen Compilerfehler verursacht. Nur um diesen Compilerfehler zu beheben, willst du nun friend einsetzen, obwohl das Problem woanders liegt.



  • Ah ok, sry das war ein Denkfehler meinerseits. Alles klar dann verwende ich +=.

    Vielen Dank an alle beteiligten Helfer 😉


Anmelden zum Antworten