csci 104
play

CSCI 104 Operator Overloading Mark Redekopp David Kempe 2 - PowerPoint PPT Presentation

1 CSCI 104 Operator Overloading Mark Redekopp David Kempe 2 Function Overloading What makes up a signature (uniqueness) of a function name number and type of arguments No two functions are allowed to have the same signature;


  1. 1 CSCI 104 Operator Overloading Mark Redekopp David Kempe

  2. 2 Function Overloading • What makes up a signature (uniqueness) of a function – name – number and type of arguments • No two functions are allowed to have the same signature; the following 5 functions are unique and allowable… – void f1(int); void f1(double); void f1(List<int>&); – void f1(int, int); void f1(double, int); • We say that “f1” is overloaded 5 times

  3. 3 Operator Overloading class User{ public: User(string n); // Constructor • C/C++ defines operators (+,*,-,==,etc.) that work string get_name(); with basic data types like int, char, double, etc. private: user.h int id_; • C/C++ has no clue what classes we’ll define and string name_; what those operators would mean for these yet- }; to-be-defined classes #include “ user.h ” – class complex { User::User(string n) { public: name_ = n; double real, imaginary; user.cpp } string User::get_name(){ }; return name_; – Complex c1,c2,c3; } // should add component-wise c3 = c1 + c2; #include<iostream> #include “user.h” – class List { ... int main(int argc, char *argv[]) { }; User u1(“Bill”), u2(“Jane”); user_test.cpp – List l1,l2; // see if same username // Option 1: l1 = l1 + l2; // should concatenate if(u1 == u2) cout << “Same”; // l2 items to l1 // Option 2: • We can write custom functions to tell the if(u1.get_name() == u2.get_name()) compiler what to do when we use these { cout << “Same” << endl; } operators ! Let us learn how… return 0: }

  4. 4 Two Approaches • There are two ways to specify an operator overload function – Global level function (not a member of any class) – As a member function of the class on which it will operate • Which should we choose? – It depends on the left-hand side operand (e.g. string + int or iostream + Complex )

  5. 5 Method 1: Global Functions • Can define global functions int main() { int hour = 9; with name "operator{+- …}" string suffix = "p.m."; taking two arguments string time = hour + suffix; // WON'T COMPILE…doesn't know how to – LHS = Left Hand side is 1 st arg // add an int and a string return 0; – RTH = Right Hand side is 2 nd arg } • When compiler encounters an string operator+(int time, string suf) { operator with objects of stringstream ss; ss << time << suf; specific types it will look for an return ss.str(); } "operator" function to match int main() { and call it int hour = 9; string suffix = "p.m."; string time = hour + suffix; // WILL COMPILE TO: // string time = operator+(hour, suffix); return 0; }

  6. 6 Method 2: Class Members • C++ allows users to write class Complex { public: functions that define what an Complex(int r, int i); ~Complex(); operator should do for a class Complex operator+(const Complex &rhs); – Binary operators: +, -, *, /, ++, -- private; – Comparison operators: int real, imag; }; ==, !=, <, >, <=, >= – Assignment: =, +=, -=, *=, /=, etc. Complex Complex::operator+(const Complex &rhs) { – I/O stream operators: <<, >> Complex temp; • temp.real = real + rhs.real; Function name starts with temp.imag = imag + rhs.imag; ‘ operator ’ and then the actual return temp; } operator int main() • Left hand side is the implied object { Complex c1(2,3); for which the member function is Complex c2(4,5); Complex c3 = c1 + c2; called // Same as c3 = c1.operator+(c2); cout << c3.real << "," << c3.imag << endl; • Right hand side is the argument // can overload '<<' so we can write: // cout << c3 << endl; return 0; }

  7. 7 Binary Operator Overloading • For binary operators, do the operation on a new object's data members and return that object – Don’t want to affect the input operands data members • Difference between: x = y + z; vs. x = x + z; • Normal order of operations and associativity apply (can’t be changed) • Can overload each operator with various RHS types… – See next slide

  8. 8 Binary Operator Overloading class Complex No special code is needed to add 3 or more { operands. The compiler chains multiple calls to public: Complex(int r, int i); the binary operator in sequence. ~Complex() Complex operator+(const Complex &rhs); Complex operator+(int real); int main() private: { int real, imag; Complex c1(2,3), c2(4,5), c3(6,7); }; Complex Complex::operator+(const Complex &rhs) Complex c4 = c1 + c2 + c3; { // (c1 + c2) + c3 Complex temp; // c4 = c1.operator+(c2).operator+(c3) temp.real = real + rhs.real; // = anonymous-ret-val.operator+(c3) temp.imag = imag + rhs.imag; return temp; } c3 = c1 + c2; c3 = c3 + 5; Complex Complex::operator+( int real ) { } Complex temp = *this; temp.real += real; return temp; } Adding different types ( Complex + Complex vs. Complex + int ) requires different overloads

  9. 9 Relational Operator Overloading • class Complex Can overload { ==, !=, <, <=, >, >= public: Complex(int r, int i); • Should return bool ~Complex(); Complex operator+(const Complex &rhs); bool operator==(const Complex &rhs); int real, imag; }; bool Complex::operator==(const Complex &rhs) { return (real == rhs.real && imag == rhs.imag); } int main() { Complex c1(2,3); Complex c2(4,5); // equiv. to c1.operator==(c2); if(c1 == c2) cout << “C1 & C2 are equal!” << endl; return 0; } Nothing will be displayed

  10. 10 Practice On Own • In the online exercises, add the following operators to your Str class – operator[] – operator==(const Str& rhs); – If time do these as well but if you test them they may not work…more on this later! – operator+(const Str& rhs); – operator+(const char* rhs);

  11. 11 Non-Member Functions int main() • What if the user changes the { Complex c1(2,3); order? Complex c2(4,5); Complex c3 = 5 + c1 ; – int on LHS & Complex on RHS // ?? 5.operator+(c1) ?? – // ?? int.operator+(c1) ?? No match to a member function // there is no int class we can b/c to call a member function // change or write the LHS has to be an instance of return 0; that class } • We can define a non- Doesn't work without a new operator+ overload member function (good old Complex operator+(const int& lhs, const Complex &rhs) regular function) that takes { Complex temp; in two parameters (both the temp.real = lhs + rhs.real; temp.imag = rhs.imag; return temp; LHS & RHS) } – int main() May need to declare it as a { friend Complex c1(2,3); Complex c2(4,5); Complex c3 = 5 + c1 ; // Calls operator+(5,c1) return 0; } Still a problem with this code Can operator+(…) access Complex's private data?

  12. 12 Friend Functions • A friend function is a class Silly { function that is not a public: member of the class but Silly(int d) { dat = d }; friend int inc_my_data(Silly &s); has access to the private private: int dat; data members of instances }; of that class // don't put Silly:: in front of inc_my_data(...) • Put keyword ‘ friend ’ in // since it isn't a member of Silly int inc_my_data(Silly &a) function prototype in class { Notice inc_my_data is NOT a s.dat++; definition member function of Silly. It's a return s.dat; • } global scope function but it Don’t add scope to now can access the private function definition int main() class members. { Silly cat(5); //cat.dat = 8 // WON'T COMPILE since dat is private int x = inc_my_data(cat); cout << x << endl; }

  13. 13 Non-Member Functions class Complex • Revisiting the previous { public: problem Complex(int r, int i); ~Complex(); // this is not a member function friend Complex operator+(const int&, const Complex& ); private: int real, imag; }; Complex operator+(const int& lhs, const Complex &rhs) { Complex temp; temp.real = lhs + rhs.real; temp.imag = rhs.imag; return temp; } int main() { Complex c1(2,3); Complex c2(4,5); Complex c3 = 5 + c1 ; // Calls operator+(5,c1) return 0; } Now things work!

  14. 14 Why Friend Functions? • Can I do the following? class Complex { • error: no match for 'operator<<' in 'std::cout << c1' public: • /usr/include/c++/4.4/ostream:108: note: Complex(int r, int i); candidates are: /usr/include/c++/4.4/ostream:165: ~Complex(); note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, Complex operator+(const Complex &rhs); _Traits>::operator<<( long int ) [with _CharT = char, private: _Traits = std::char_traits<char>] int real, imag; • /usr/include/c++/4.4/ostream:169: note: }; std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, int main() _Traits>::operator<<( long unsigned int ) [with { _CharT = char, _Traits = std::char_traits<char>] Complex c1(2,3); • /usr/include/c++/4.4/ostream:173: note: cout << c1; // equiv. to cout.operator<<(c1); std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, cout << endl; _Traits>::operator<<( bool ) [with _CharT = char, return 0; _Traits = std::char_traits<char>] } • /usr/include/c++/4.4/bits/ostream.tcc:91: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<( short int ) [with _CharT = char, _Traits = std::char_traits<char>]

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend