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

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • 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

    The post was edited 1 time, last by 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:

    Source Code

    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. };
    Display All

    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 wrote:

    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?

    Source Code

    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. }
    Display All


    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:

    Source Code

    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. };
    Display All


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

    Source Code

    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. };
    Display All

    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

    The post was edited 2 times, last by superuser ().

  • achso

    std::ostream& operator<<( std::ostream& o, myStruct& c)

    das Beispiel kann man ja umwandeln zu

    typ& operator<<(MyStrukt& s, myClass& c)
    dann ginge das - interessant - Operatoren sind ja eh nur Abkürzungen für Funktionen, meist ist das nur Aufwand, die extra zu implementieren