Download presentation
Presentation is loading. Please wait.
1
Lecture 4 OOP Course
2
4. Operators
3
Using constructors: String int main(){ String s1(“My String”); String s2(s1); String s3; s3=s1; } int main(){ String s1(“My String”); String s2(s1); String s3=s1; } What’s the difference?
4
Operators Definition We want User-defined types to behave the same way as built-in types We want operators to be supported, for the uniform convention The language allows this And the usage: class String { char* chars; int length; public: String(); String(char* value); ~String(); String& operator=(const String& s); bool operator>(const String& s); String& operator+=(const String& s); char* getString(); void setString(char* value); };
5
Operators - Usage Who is the caller? Who is the parameter? void main() { String s1 =“OOP ”; String s2 =“Course”; s1 += s2; } Invokes “function” s1.operator+=(s2)
6
Operators - Implementation bool String::operator>(const string& s) { return strcmp(m_str, s.m_str) > 0; }
7
Operators - Implementation String &String::operator+=(const String &s){ int new_len = length + s.length + 1; char *v = new char [new_len]; strcpy(v, chars); strcat(v, s.chars); delete[] chars; chars = v; length = new_len; return *this; } Within a member function: explicit name for the object on which the function is called
8
Operators – Implementation (first version) String String::operator+(const String &s){ String tmp = *this; tmp += s; return tmp; }
9
Operators: Good news Can be defined and re-defined =Defined by default: = Rules: –At least one operand must be class –Cannot define new operators –Cannot change precedence/associativity
10
operators overloading - what can we overload? + - * / % ^ & | ! = +=-=*=/=%= ^=&=|= > >=== != =&&||++--, ->*->()[] what not ?..* :: ? : sizeof
11
Example: Class Vector class Vector2D{ private: double x, y; public: Vector2D(double x_init=0, double y_init=0): x(x_init), y(y_init){} double getX() const {return x;} double getY() const {return y;} Vector2D add(const Vector2D& other) const {return Vector2D(x+other.x, y+other.y);} } //usage: Vector2D a(3,2), b(1); Vector2D c = a.add(b); cout << “(“ << c.getX() << “,” << c.getY() << ‘)’;
12
Example: Class Vector class Vector2D{ private: double x, y; public: Vector2D(double x_init=0, double y_init=0): x(x_init), y(y_init){} double getX() const {return x;} double getY() const {return y;} Vector2D operator+(const Vector2D& other) const {return Vector2D(x+other.x, y+other.y);} {return Vector2D(x+other.x, y+other.y);} } //usage: Vector2D a(3,2), b(1); Vector2D c = a+b; cout << “(“ << c.getX() << “,” << c.getY() << ‘)’;
13
Overloading ++ and -- Pre- and post-increment –x = 0; cout << x++; cout <<++x; Pre-increment and pre-decrement – –Vector2D operator++(); Post-increment and post-decrement – use dummy parameter –Vector2D operator++(int);
14
Friend access modifier The following will work: –c=a+b –c=a+1; The following will not work: –c=1+b The first argument cannot be built-in! Solution: define the operator not as a member function –But what about encapsulation? friend :Access modifier friend : allows to access private fields and methods of the class
15
Example: Class Vector class Vector2D{ private: double x, y; public: Vector2D(double x_init=0, double y_init=0): x(x_init), y(y_init){} double getX() const {return x;} double getY() const {return y;} friend Vector2D operator+( const Vector2D& left, const Vector2D& right); } Vector2D operator+(const Vector2D& left, const Vector2D& right){ return Vector2D(left.x+right.x, left.y+right.y);} //usage: Vector2D a(3,2), b(1); Vector2D c = a+b; cout << “(“ << c.getX() << “,” << c.getY() << ‘)’;
16
Class Vector: more operators class Vector2D{... Vector2D operator-() const{return Vector2D(-x, -y);} double operator[](int index) const {return (index == 0)?x:y;} friend ostream& operator<<( ostream& ostr, const Vector2D& v); } ostream& operator<<(ostream& ostr, const Vector2D& v){ return ostr << “(“ << v.x << “,” << v.y << ‘)’; } //usage: Vector2D a(3,2), b(1); Vector2D c = -a; cout << “(“ << c[0] << “,” << c[1] << ‘)’; cout << c << b << a;
17
Member vs. non-member operators Use membersUse members –When returning a reference operators =, [] –Unary operators, usually –Asymmetric operators, whenever possible Use friends forUse friends for –Symmetric operators –Operators on classes which cannot be altered istream, ostreamh
18
5 Operator=
19
operator= By default: bitwise copy Vector2D –Will this work for Vector2D? String –Will this work for String? Rule of thumb: either you need all of {destructor, copy-constructor, operator=} or you need none Rules: MyClass& MyClass::operator=(const MyClass& other) *this –Return *this –Define as member to ensure target object is assignable
20
operator= : example class String{... public: String& operator=(const String& other){ if (this == &other) return *this; if (chars != NULL) delete[] chars; length = other.length; chars = new char[length+1]; strcpy(chars, other.chars); return *this; }
21
Operator examples
22
The Rational Number Class class Rational { public: Rational(int top = 0, int bottom = 1}: t(top), b(bottom) { normalize();} //... private: int t,b; void normalize() // A private member function {if(b<0) { b = -b; t = -t; } int divisor = gcd(abs(t),b); t /= divisor; b /= divesor; } }; gcd defined elsewhere
23
A Unary Operator Member class Rational { //... public: //... Rational operator-() const { return Rational(-t,b);} //... }; int main() { Rational r(-1,3); Rational s = -r; // Activates r.operator-().... }
24
Arithmetic Operator Members class Rational { //... public: //... Rational& operator+=(const Rational& r) const{ t = t*r.b+r.t*b; b = b*r.b; normalize(); return *this; } Rational& operator-=(const Rational& r) const{ t = t*r.b-r.t*b; b = b*r.b; normalize(); return *this; } };
25
Arithmetic Operator Members class Rational { //... public: //... Rational& operator*=(const Rational& r) const{ t = t*r.t; b = b*r.b; normalize(); return *this; } Rational& operator/=(const Rational& r) const{ t = t*r.b; b = b*r.t); normalize(); return *this; } };
26
Symmetric Operators class Rational { //... public: //... }; Rational operator+(const Rational& r1, const Rational& r2){...} Rational operator-(const Rational& r1, const Rational& r2){...} Rational operator*(const Rational& r1, const Rational& r2) { Rational tmp(r1); return tmp*=r2; } friend Rational operator/(const Rational& r1, const Rational& r2){...}
27
Friends Operators class Rational { //... public: //... friend bool operator==(const Rational&, const Rational&); friend bool operator!=(const Rational&, const Rational&); friend bool operator<=(const Rational&, const Rational&); friend bool operator>=(const Rational&, const Rational&); friend bool operator<(const Rational&, const Rational&); friend bool operator>(const Rational&, const Rational&); }; Not all of them need to be friend
28
Adding I/O to the Rational Class class Rational { public: //... friend istream& operator>>(istream& in, Rational& r); friend ostream& operator<<(ostream& out, Rational& r); }; istream& operator>>(istream& in, Rational& r){ in >> r.t >> r.b; return in; } ostream& operator<<(ostream& out, Rational& r){ out << r.t << '\' << r.b; return out; }
29
Using I/O in the Rational Class int main() { Rational r1(1,6), r2(1,3); cout << r1 << '+' << r2 << '=' << r1+r2 << endl; // will print: 1/6 + 1/3 = 1/2 return 0; }
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.