> For the complete documentation index, see [llms.txt](https://lauradang.gitbook.io/notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lauradang.gitbook.io/notes/c++/cs_246/lecture-13.md).

# Lecture 13

**Recall:**

* encapsulated list class
* can't traverse the list node-to-node
* repeatedly calling ith => O(n2) time

### SE Topic: Design Patterns

* certain programming problems arise often
* keep track of good solutions to these problems reuse and adapt them
  * If you have this problem, then this technique may solve it
  * **Our problem:** traversing a list without resulting in O(n2) time while keeping nodes secure
  * **Solution:** Iterator Pattern

### Iterator Pattern

* Create a class that manages access to nodes
* Abstraction of a pointer
* Walk the list without exposing the actual pointers

Iterating through an array in C-style

```
for (int *p = arr; p < arr + size; ++p) {
  cout << *p << endl;
}
```

* Want class that acts as pointer p

```
class List {
  struct Node;
  Node *theList;

  public:
    class Iterator {
      Node *p; // think of pointer as your bookmark (where am I in the array)
      public:
        explicit Iterator (Node *p): p{p}{}
        Iterator &operator++() {
          p = p->next; 
          return *this;
        } 
        
        int &operator*() {
          return p->data;
        } // O(1)
        
        bool operator!= (const Iterator &other) {
          return p != other.p;
        } // O(1)
    };
    
    Iterator begin() {
      return Iterator{theList};
    } // O(1)
    
    Iterator end() { // O(1)
      return Iterator{nullptr;}
    }
}
```

Now what does client's code look like?

```
int main() {
  List l;
  l.addToFront(1);
  l.addToFront(2);
  l.addToFront(3);
  
  for (List::Iterator it=l.begin(); it != l.end(); ++it) { 
    cout << *it << endl;
  } // Now this runs in O(n) time instead of O(n^2)
}
```

Shortcut: automatic type deduction

### Automatic Type Deduction

```
// gives x the same type as the value of y
auto x = y;
```

Applying the shortcut:

```
for (auto its=l.begin(); l != l.endl(); ++it) {
  cout << *it << endl;
}
```

An even shorter shortcut:

```
// bi-value declaration: n is a copy of the list item
for (auto n:l) {
  cout << n << endl;
}

// If you want to modify list items or save copy
for (auto &n:l) {
  ++n;
}

// OR
for (const auto &n:l) {
  ...
}
```

### Range Loops

* available for any class with:
  * methods `begin` and `end` that produce iterators
  * the iterator must support `!=`, prefix `++`, unary `*`

## Encapsulation continued

### Encapsulation with Constructors

* List client can create iterators directly by doing:

```
auto it = List::Iterator {nullptr};
```

* Violates encapsulation
  * client should be using end()
* We could make Iterator's constructor private, but two problems arise:
  1. Client cannot call `List::Iterator`
  2. List cannot call `Iterator`

**Problem:** How do we allow client to create iterators without breaking encapsulation? **Solution:** Make `List` a *friend* of `Iterator`

### Friends

* Gives class privileged access to another class

**Solution explained:**

* Make List a *friend*
  * give List privileged access to Iterator by making List a *friend*
* So now List can still create iterators, but client can only create iterators by calling begin/end

```
class List {
  ...
  public:
    class Iterator {
      Node *p;
      explicit Iterator(Node *p);
    public:
      ...
      friend class List; // List has access to all members of Iterator
    };
  ...
};
```

**Rule of Thumb with Friends**: Give your classes as few friends as possible - weakens encapsulation

### Accessor/Mutator Methods

* Provides access to private fields

```
class Vec {
  int x,y;
  public:
    ...
    int getX() const { // accessor
      return x;
    } 
    void getY(int z) { // mutator
      y=z;
    }
};
```

**Why not just put int x and y in public?**

* advantage to this is if you want x and y to have certain restrictions, but not complete restriction

#### Dealing with private fields for the`operator<<`?

* operator<< needs to access x and y fields, but the operator function cannot be a member (needs to be outside the class)
* We have two options in this case:
  1. if `getX`, `getY` defined, then use these methods to access x and y
  2. if you don't want to provide getX and getY - make `operator<<` a friend function:

```
// .h
class Vec {
  ...
  friend std::ostream &operator<< (std::ostream &out, const Vec &v);
// not a member function, this is a friend declaration (still has two arguments, one of them do not become this)
}

// .c
ostream &operator<<(ostream &out, const Vec &v) {
  return out << v.x << ' ' << v.y;
}
```

## System Modelling (UML)

* Visualizing the structure of the system (abstractions and relationships among them) to aid design and implementation Popular Standard: **UML** (Unified Modelling Language)

### Modeling Classes

| **Name**           | **\*\*Vec**                    |
| ------------------ | ------------------------------ |
| Fields (optional)  | -x: Integer, -y: integer       |
| Methods (optional) | +getX: Integer, +getY: Integer |

\*\*Visibility: - means private, + means public, # means protected

### Relationship: Composition of classes

```
class Vec {
  int x,y,z;
  public:
    Vec(int, int, int);
};

// Two vecs define a plane:
class Plane {
  Vec v1, v2;
  ...
};

// This does not compile
Plane p; // can't initialize v1 and v2 without help - no default constructor for vec

class Plane {
  Vec v1, v2;
  public:
    // means initialize v1 to Vec {1,0,0};
    Plane(): v1{1,0,0}, v2{0,1,0}, v3{0,0,1} {} 
    ...
}
```

### Composition (OWNS-A)

* Embedding an object inside another

**Example:**

* Embedding Vec inside Plane is called composition.

**Relationship shown in example:**

* A Plane **OWNS-A** Vec (Owns 2 of them)
* If A **OWNS-A** B, then typically: B has no identity outside A (no independent existence)
  * If A is destroyed, B is destroyed
  * If A is copied, B is copied (deep copy)
* eg. A car owns four wheels - a wheel is part of a car
  * destroy the car => destroy the wheels
  * copy the car => copy the wheels
* **Typical Implemention:** typically as composition of classes
* Modelling: Plane

#### UML

![](https://github.com/lauradang/wiki-notes/blob/master/Users/lauradang/Desktop/CS246/UMLs/composition.jpg)
