.* ?: sizeof">

# 1 Data Structures - CSCI 102 CS102 C++ Operator Overloading Prof Tejada.

## Presentation on theme: "1 Data Structures - CSCI 102 CS102 C++ Operator Overloading Prof Tejada."— Presentation transcript:

1 Data Structures - CSCI 102 CS102 C++ Operator Overloading Prof Tejada

3 Data Structures - CSCI 102 Operator Overloading C++ has tons of built-in operators (e.g. +,-,<<, etc.) They work on built-in types (e.g. int, string) They don’t work on your own classes! string a = "hello "; string b = " world!"; string c = a + b; //addition cout << c << endl; //print to console String is a class, so why does this work? Since C++ doesn’t know how to do this stuff by default, we have to tell it how

Rules 4 Data Structures - CSCI 102 Operator Overloading You can only overload an operator that has at least one user defined type (i.e. you can’t overload "int + int") You can only overload existing operators, you can’t create your own new ones All operators keep their normal associativity & precedence You can’t overload any of these ::. ->.* ?: sizeof

5 Data Structures - CSCI 102 The Point Class class Point { private: int x; int y; public: Point() { x=0; y=0; } Point(int newx, int newy) { x=newx; y=newy; } int getX() const { return x; } int getY() const { return y; } void setX(int newx) { x=newx; } void setY(int newy) { y=newy; } };

You can implement all the operators in C++ as a function call somewhere behind the scenes Point p1(10,10), p2(50,50); Point p3 = p1 + p2; When you see something like this: 6 Data Structures - CSCI 102 The + Operator You should really picture it like this: Should this function be a member of the Point class? It can be, but it doesn’t really need to be (no changes are made to p1 or p2) Could we get access to the private data of "a" and "b" without being part of class "Point"? Point operator+(const Point &a, const Point &b)

The function isn’t a class member function What does it mean to tag a function as a friend of a class? 7 Data Structures - CSCI 102 The friend Keyword The function can still access to the private data of the class Most of the time it is, but it’s useful for operators that don’t modify class data That sounds like a horrible idea! friend functions should only read "private" class data, they shouldn’t modify it Don’t break encapsulation Avoid using friend in general is probably not a bad policy Remember, C++ is built for speed

class Point {... friend Point operator+(const Point &a, const Point &b);... }; //this is NOT a member function (no Point::needed) Point operator+(const Point &a, const Point &b) {... } 8 Data Structures - CSCI 102 The friend Keyword

p1 += p2;//we’re changing p1 here Instead of defining it as a friend function, we just define it as a normal class function class Point {... void operator+=(const Point &b);... }; 9 Data Structures - CSCI 102 The += Operator If the operator actually changes one of its operands, it’s better off as a member function Point p1(10,10), p2(50,50);

Point p1(5,10); cout << p1 << endl; Isn’t it annoying that this code doesn’t normally work? It can work! Overload the insertion operator (<<)! ostream& operator<<(ostream& out,const Point &b) 10 Data Structures - CSCI 102 The Insertion Operator (<<) This function looks a lot different than the others What is ostream &out? Why is it not const? Why does it return ostream&? NOTE: It cannot be a class member function NOTE: ostream is std::ostream from NOTE: cout << p1 << endl means (cout << p1) << endl

Point p1; cin >> p1; How can we read in something then? Overload the extraction operator (>>) istream& operator>>(istream& in, Point &b) 11 Data Structures - CSCI 102 The Extraction Operator (>>) What is istream &in? This function looks a lot different than the others Why does it return istream&? Why is Point &b not const? NOTE: It cannot be a class member function NOTE: cin >> p1 >> p2 means (cin >> p1) >> p2

Comparison operators can be reused to define each other since many of them act as logical opposites Point p1(10,10), p2(10,10); if(p1 == p2) cout << "They’re equal!" << endl; What about comparing two instances of a class? It still looks like what we’re used to: bool operator==(const Point &a, const Point &b) Comparison always return bool == vs. != >= vs. < 12 Data Structures - CSCI 102 Comparison Operators

13 Data Structures - CSCI 102 Unary Operators Some other things to consider Point p1(10,10); Point p2 = -p1; Some operators only take in a single argument This looks a bit different too: Point operator-(const Point &a) Why does it return a Point? Why does it only have one argument? How does C++ know we’re not trying to redefine subtraction instead? Other unary operators include ! and + Can also be: Point operator-()

14 Data Structures - CSCI 102 What Other Stuff Can You Overload? Point p1(10,10); cout << p1[0]; Subscript ([]) Prefix/Postfix Increment/Decrement (++, --) Equality (==) And many, many more

Data Structures - CSCI 102 point.h #ifndef POINT_H_ #define POINT_H_ class Point { private: int x; int y; public: Point() { x = y = 0; } Point(int newx,int newy) { x = newx; y = newy; } x; } y; } newx; } newy; } int getX() const { return int getY() const { return void setX(int newx) { x = void setY(int newy) { y =

18 Data Structures - CSCI 102 point.h (Cont...) void operator+=(const Point& a); void operator+=(const int value); int& operator[](const int index); void operator++(); //prefix (e.g. ++point) void operator++(int dummy); //postfix (e.g. point++) Point operator-(); bool operator==(const Point& another_point); bool operator!=(const Point& another_point); }; Point operator+(const Point& a,const Point& b); Point operator+(const Point& a,const int b); Point operator+(const int a,const Point& b); std::ostream& operator<<(std::ostream& out, const Point& b); std::istream& operator>>(std::istream& in, Point& b); #endif /* POINT_H_ */

19 Data Structures - CSCI 102 point.cpp #include using namespace std; #include "point.h" Point operator+( const Point& a, const Point& b) { Point p; p.setX(a.getX()+b.getX()); p.setY(a.getY()+b.getY()); return p; Point operator+( const Point& a, const int b) { Point p; p.setX(a.getX()+b); p.setY(a.getY()+b); return p; } Point operator+( const int a, const Point& b) { return b + a; } ostream& operator<<( ostream& out, const Point& b) { out << "(" << b.getX() << "," << b.getY() << ")"; return out; } istream& operator>>( istream& in, Point& b) int x, y; in >> x >> y; b.setX(x); b.setY(y); return in; {}{}

bool Point::operator==( const Point& b) { return x == b.getX() && y == b.getY(); bool Point::operator!=( const Point& b) { return !((*this) == b); } void Point::operator+=( const Point& b) { this->x += b.getX(); this->y += b.getY(); } Point Point::operator-() { Point p; p.setX(-(this->x)); p.setY(-(this->y)); return p; } 20 Data Structures - CSCI 102 point.cpp (Cont...) void Point::operator++() { this->x++; this->y++; } void Point::operator++(int dummy) { ++(*this); } int& Point::operator[]( const int index) { if(index == 0) { return this->x; } else if(index == 1) { return this->y; } throw out_of_range( "Point index was out of bounds"); }