upgrade structures and migrate to nextra v4
This commit is contained in:
171
content/CSE332S/CSE332S_L11.md
Normal file
171
content/CSE332S/CSE332S_L11.md
Normal file
@@ -0,0 +1,171 @@
|
||||
# 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:
|
||||
|
||||
```cpp
|
||||
// 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:
|
||||
|
||||
```cpp
|
||||
// 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
|
||||
|
||||
```cpp
|
||||
// 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.
|
||||
|
||||
```cpp
|
||||
// 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
|
||||
|
||||
```cpp
|
||||
// function pointer
|
||||
bool (*PF) (const string &, const string &);
|
||||
// function
|
||||
bool string_func (const string &, const string &);
|
||||
```
|
||||
|
||||
- A struct or class providing an overloaded `operator()`
|
||||
|
||||
```cpp
|
||||
// an example of self-defined operator
|
||||
struct strings_ok {
|
||||
bool operator() (const string &s, const string &t) {
|
||||
return (s != "quit") && (t != "quit");
|
||||
}
|
||||
};
|
||||
```
|
||||
Reference in New Issue
Block a user