operator-overloading für existierende (C-) structs

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • operator-overloading für existierende (C-) structs

    Hallo,
    ich möchte für einen bereits existierenden Datentyp aus einer (C-)Fremdbibliothek, die Operatoren "<<" und ">>" überladen. Hierzu zwei Fragen:
    1. Ist es überhaupt möglich, bei bereits existierenden Datentypen Operatoren zu überladen? Und wenn ja, wie wäre sähe das syntaktisch aus (also wo und wie definieren, etc...)?
    2. Ist das Ganze darüberhinaus auch für C-Structs möglich wenn diese in einem C++ Programm verwendet werden?

    Danke schon einmal!
    >: 4 8 15 16 23 42
  • 1. ja
    In Deiner Klasse A kann man schreiben

    Rueckgabewert operator>>(RechtesArgument); // (**)

    Rechtes Argumente ist aus Klasse B und man könnte zumindest A>>B machen

    Andersrum muss mans entweder global machen, ODER Klasse ableiten und Funktion "überschreiben" - sicher lässt sich auch was mit "friend" machen.

    Interessant: tutorial.schornboeck.net/operatoren_ueberladung.htm
    Besser noch die 2. Seite dazu: tutorial.schornboeck.net/operatoren_ueberladung2.htm - wobei hier konkret nur die "cout"-Klasse betrachtet wird, das ist zu beachten !

    Mit "normalen" Datentypen (int, double) gibts Schwierigkeiten, weil z.B. 1 und 'a' als const-Parameter irgendwie übergeben wird, da muss man sich mit dem const-zeug rumärgern, damit der Compiler das frisst.

    Also prinzipiell ist alles machbar :-p

    2. Ich bin mir nicht sicher, ob (**) auch bei strukts geht, im Prinzip sind die Operatoren ja nur ganz normale Funktionen, also wenn links ne Klasse steht, kann rechts auch ein Strukt mit >> und << drauf losgelassen werden. Links ein Strukt ist logisch nicht möglich, andererseits ist ein Strukt ja auch bloß ne Klasse ohne Funktionen ;) - kann man sicher recht flott nen Wrapper drum schreiben, in dem man dann die Operatoren auch definieren kann.

    Tipp - bei "symmetrischen" Funktionen, also A+B und B+A, würde es Sinn machen die Funktion "addieren(A,B)" zu definieren und per friend oder halt sowieso als public dann in beiden Klassen in den Operator stecken.

    btw. ich hab keine Ahnung, nur so halb, daher mal als "laut gedacht" konsumieren - wobei ich schonmal ne Vektor/Matrix-Klasse geschrieben hab, aber das const hat mich dann angekotzt irgendwann.

    Noch sinnloses Extrawissen: Bei Vektoren soll man ja auch machen können: "Vektor[2]=4" sowie "i=Vektor[2]"
    Dann hat man ja: "double operator[](int)", dann ginge die 1. Variante NICHT, wenn man jedoch statt "double" die Referenz "double&" hinschreibt, kriegt ers hin (glaube) - man findet nicht viele Infos wenn der Kompiler die Variante 1 nicht frisst.

    hm, das Tutorial tutorial.schornboeck.net ist bei Google immer ganz oben - interessant

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von zyklo ()

  • structs sind in C++ nichts anderes als Klassen. Der einzigste Unterschied ist, dass structs by default public sind und Klassen by default private.
    Beispiel:

    Quellcode

    1. class myClass
    2. {
    3. int a;
    4. };
    5. struct myStruct
    6. {
    7. int a;
    8. };
    9. int main()
    10. {
    11. myClass a;
    12. a.a = 0; // Fehler
    13. myStruct b;
    14. b.a = 0; // ok
    15. };
    Alles anzeigen

    Also kann man auch die operatoren global überladen :) ohne dass man einen friend braucht.
    rya.
    Sometimes it pays to stay in bed in Monday, rather than spending the rest of the week debugging Monday's code. ~Dan Salomon
  • zyklo schrieb:

    Du meinst also, dass frei nach Deinem Quelltext, funktionieren müsste:

    myStrukt << myClass

    dann müsste man eine Funktion definieren IN myStrukt mit operator<<(myClass) ... halte ich für unwahrscheinlich, dass das möglich ist ;)


    So?

    Quellcode

    1. #include <iostream>
    2. struct myStruct
    3. {
    4. int a;
    5. int b;
    6. };
    7. class myClass
    8. {
    9. public:
    10. int a;
    11. int b;
    12. };
    13. myClass& operator << ( myClass& c, myStruct& s)
    14. {
    15. c.a = s.a;
    16. c.b = s.b;
    17. return c;
    18. }
    19. std::ostream& operator<<( std::ostream& o, myClass& c)
    20. {
    21. o << "A: " << c.a << std::endl;
    22. o << "B: " << c.b << std::endl;
    23. return o;
    24. }
    25. std::ostream& operator<<( std::ostream& o, myStruct& c)
    26. {
    27. o << "A: " << c.a << std::endl;
    28. o << "B: " << c.b << std::endl;
    29. return o;
    30. }
    31. int main()
    32. {
    33. myStruct a;
    34. myClass b;
    35. a.a = 1337;
    36. a.b = 42;
    37. b << a;
    38. std::cout << "Struct: " << std::endl << a;
    39. std::cout << "Class: " << std::endl << b;
    40. }
    Alles anzeigen


    edit: Example erweitert.
    Kopieren, Compilieren, Staunen...


    Noch sinnloses Extrawissen: Bei Vektoren soll man ja auch machen können: "Vektor[2]=4" sowie "i=Vektor[2]"
    Dann hat man ja: "double operator[](int)", dann ginge die 1. Variante NICHT, wenn man jedoch statt "double" die Referenz "double&" hinschreibt, kriegt ers hin (glaube) - man findet nicht viele Infos wenn der Kompiler die Variante 1 nicht frisst.

    So sinnlos ist dieses Wissen nicht. Es gibt 2 Methoden um den []-operator zu überladen:

    1.) Man möchte nur den Wert anzeigen

    Da nimmt man eine const-Referenz oder eine Kopie. Hence the code:

    Quellcode

    1. #include <exception>
    2. class Vector
    3. {
    4. public:
    5. const int& operator[] ( const int index )
    6. {
    7. switch(index)
    8. {
    9. case 0: return a;
    10. case 1: return b;
    11. default: throw(std::exception("out of range!"));
    12. }
    13. }
    14. private:
    15. int a;
    16. int b;
    17. };
    Alles anzeigen


    2.) Man möchte mit dem Wert direkt arbeiten, dann nimmt man ne referenz:

    Quellcode

    1. #include <exception>
    2. class Vector
    3. {
    4. public:
    5. int& operator[] ( const int index )
    6. {
    7. switch(index)
    8. {
    9. case 0: return a;
    10. case 1: return b;
    11. default: throw(std::exception("out of range!"));
    12. }
    13. }
    14. private:
    15. int a;
    16. int b;
    17. };
    Alles anzeigen

    Damit ändert man dann der Wert in der Klasse direkt.

    Mfg
    Sometimes it pays to stay in bed in Monday, rather than spending the rest of the week debugging Monday's code. ~Dan Salomon

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von superuser ()