Files
NoteNextra-origin/content/CSE332S/CSE332S_L11.md
2025-07-06 12:40:25 -05:00

4.5 KiB

CSE332S Lecture 11

Operator overloading intro

Insertion operator (<<) - pushes data from an object into an ostream

Extraction operator (>>) - pulls data off of an istream and stores it into an object

Defined for built-in types, but what about user-defined types?

Operator overloading - we can provide overloaded versions of operators to work with objects of our classes and structs

Example:

// declaration in point2d.h

struct Point2D {
    Point2d(int x, int y);
    int x_;
    int y_;
}

// definition in point2d.cpp
Point2D::Point2D(int x, int y): x_(x), y_(y) {}

// main function
int main() {
    Point2D p1(5,5);
    cout << p1 << endl; // this is equivalent to calling `operator<<(ostream &, const Point2d &);` Not declared yet.
    cout <<  "enter 2 coordinates, separated by a space" << endl;
    cin >> p1; // this is equivalent to calling `operator>>(istream &, const Point2d &);` Not declared yet.
    cout << p1 << endl;
    return 0;
}

Example of declaration of operator:

// declaration in point2d.h
struct Point2D {
    Point2D(int x, int y);
    int x_;
    int y_;
}

istream & operator>> (istream
&, Point2D &);

ostream & operator<< (ostream
&, const Point2D &);

// definition in point2d.cpp
Point2D::Point2D(int x, int y): x_(x), y_(y) {}

istream & operator>> (istream &i, Point2d &p) {
    // we will change p so don't put const on it
    i >> p.x_ >> p.y_;
    return i;
}
ostream & operator<< (ostream &o, const Point2D &p) {
    // we will not change p, so put const
    o << p.x_ <<   << p.y_;
    return o;
}

Operator overloading: Containers

Require element type they hold to implement a certain interface:

  • Containers take ownership of the elements they contain - a copy of the element is made and the copy is inserted into the container (implies element needs a copy constructor)
  • Ordered associative containers maintain order with elements < operator
  • Unordered containers compare elements for equivalence with == operator
// declaration in point2d.h
struct Point2D {
    Point2D(int x, int y);
    bool operator< (const Point2D &) const;
    bool operator== (const Point2D &) const;
    int x_;
    int y_;
}
// must be a non-member
operator istream & operator>> (istream &, Point2D &);
// must be a non-member
operator ostream & operator<< (ostrea &, const Point2D &);

// definition in point2d.cpp
// order by x_ value, then y_
bool Point2D::operator<(const Point2D & p) const {
    if(x_ < p,x_) {return true;}
    if(x_ == p.x_) {
        return y_ < p.y_;
    }
    return false;
}

Operator overloading: Algorithms

Require elements to implement a specific interface - can find what this interface is via the cpp reference pages

Example: std::sort() requires elements implement operator<, std::accumulate() requires operator+

Suppose we want to calculate the centroid of all Point2D objects in a vector<Point2D>

We can use accumulate() to sum all x coordinates, and all y coordinates. Then divide each by the size of the vector.

By default, accumulate uses the elements + operator.

// declaration, within the struct Point2D declaration in point2d.h, used by accumulate algorithm
Point2D operator+(const Point2D &) const;

// definition, in point2d.cpp
Point2D Point2D::operator+ (const Point2D &p) const {
    return Point2D(x_ + p.x_, y_ + p.y_);
}

// in main()
// assume v is populated with points
Point2D accumulated = accumulate(v.begin(), v.end(), Point2D(0,0));

Point2D centroid (accumulated.x_/v.size(), accumulated.y_/v.size());

Callable objects

Make the algorithms even more general

Can be used parameterize policy

  • E.g., the order produced by a sorting algorithm
  • E.g., the order maintained by an associative containers

Each callable object does a single, specific operation

  • E.g., returns true if first value is less than second value

Algorithms often have overloaded versions

  • E.g., sort that takes two iterators (uses operator<)
  • E.g., sort that takes two iterators and a binary predicate, uses the binary predicate to compare elements in range

Callable Objects

Callable objects support function call syntax

  • A function or function pointer
// function pointer
bool (*PF) (const string &, const string &);
// function
bool string_func (const string &, const string &);
  • A struct or class providing an overloaded operator()
// an example of self-defined operator
struct strings_ok {
    bool operator() (const string &s, const string &t) {
        return (s != "quit") && (t != "quit");
    }
};