CSCI 104 Operator Overloading

CSCI 104 Operator Overloading

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; 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 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; user.cpp double real, imaginary; } }; string User::get_name(){ return name_; – Complex c1,c2,c3; } // should add component-wise c3 = c1 + c2; #include<iostream> – class List { #include “user.h” ... int main(int argc, char *argv[]) { }; User u1(“Bill”), u2(“Jane”); user_test.cpp – List l1,l2; // see if same username l1 = l1 + l2; // should concatenate // Option 1: // l2 items to l1 if(u1 == u2) cout << “Same”; • We can write custom functions to tell the // Option 2: 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 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 Method 1: Global Functions int main() • Can define global functions { int hour = 9; with name "operator{+-…}" string suffix = "p.m."; taking two arguments string time = hour + suffix; st // WON'T COMPILE…doesn't know how to – LHS = Left Hand side is 1 arg // add an int and a string nd return 0; – RTH = Right Hand side is 2 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 Method 2: Class Members class Complex • C++ allows users to write { 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 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 Binary Operator Overloading class Complex { No special code is needed to add 3 or more public: operands. The compiler chains multiple calls to Complex(int r, int i); the binary operator in sequence. ~Complex() Complex operator+(const Complex &rhs); Complex operator+(int real); private: int main() int real, imag; { }; Complex c1(2,3), c2(4,5), c3(6,7); Complex Complex::operator+(const Complex &rhs) { Complex c4 = c1 + c2 + c3; Complex temp; // (c1 + c2) + c3 temp.real = real + rhs.real; // c4 = c1.operator+(c2).operator+(c3) temp.imag = imag + rhs.imag; // = anonymous-ret-val.operator+(c3) return temp; } c3 = c1 + c2; Complex Complex::operator+( int real ) c3 = c3 + 5; { Complex temp = *this; } temp.real += real; return temp; } Adding different types (Complex + Complex vs. Complex + int) requires different overloads 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 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 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) ?? – No match to a member function // ?? int.operator+(c1) ?? // 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 that class return 0; } • 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) } – May need to declare it as a int main() { 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 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 { s.dat++; Notice inc_my_data is NOT a definition return s.dat; member function of Silly. It's a • Don’t add scope to } global scope function but it 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 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 Why Friend Functions? • Can I do the following? class Complex • error: no match for 'operator<<' in 'std::cout << c1' { • /usr/include/c++/4.4/ostream:108: note: public: candidates are: /usr/include/c++/4.4/ostream:165: Complex(int r, int i); note: std::basic_ostream<_CharT, ~Complex(); _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, _Traits>::operator<<(long unsigned int) [with int main() _CharT = char, _Traits = std::char_traits<char>] { • /usr/include/c++/4.4/ostream:173: note: Complex c1(2,3); std::basic_ostream<_CharT, _Traits>& cout << c1; // equiv. to cout.operator<<(c1); 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>] 15 Why Friend Functions? • cout is an object of type ‘ostream’ class Complex { • << is just an operator public: Complex(int r, int i); • But we call it with ‘cout’ on the ~Complex(); LHS which would make Complex operator+(const Complex &rhs); private: “operator<<“ a member function int real, imag; of class ostream }; • Ostream class can’t define these int main() { member functions to print out Complex c1(2,3); user defined classes because they cout << “c1 = “ << c1; // cout.operator<<(“c1 = “).operator<<(c1); haven’t been created // ostream::operator<<(char *str); • Similarly, ostream class doesn’t // ostream::operator<<(Complex &src); have access to private members cout << endl; of Complex return 0; } 16 Ostream Overloading class Complex • Can define operator { public: functions as friend Complex(int r, int i); functions ~Complex(); Complex operator+(const

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    18 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us