---
# System prepended metadata

title: PHAS0100 - week 4
tags: [teaching, class, phas0100]

---

# PHAS0100 - week 4

### 2pm-5pm Friday 4th February

:::info
## :tada: Welcome to the 4th live-class!

#### Reminder: both groups are now merged into this Friday class

### Today

Today we will learn about

- Dependency injection and programming to interfaces
- The RAII pattern: aquire resources in constructor,  
- Templates: function template, class templates, template specialisation
- 💻 :ok_hand:
:::

### Timetable for this afternoon
    
| Start | End | Topic  | 
| -------- | -------- | -------- | 
| 14:05     | 14:35     | Lecture part 1: Dependency injection, program to interfaces, RAII | 
| 14:35 | 14:55 | Breakout/coding: Excercise 19 |
| 15:55 | 15:05 | Break | --- |
| 15:05     |  15:30     | Breakout/coding: Excercise 19 (cont) and exercise 20 | 
| 15:30 | 15:55 | Lecture part 2: Function and class templates |
| 15:55 | 16:05 | Break | --- |
| 16:05     | 16:45     | Breakout/coding: Exercise 21 | 
| 16:45 | 16:55 | Summary and closeout  |

Exercises 22 and 23 are the homework exercises for this week.

### Project templates

<details>
    
- [CMakeHelloWorld](https://github.com/UCL/CMakeHelloWorld) - Single `.cpp` file
- [CMakeLibraryAndApp](https://github.com/UCL/CMakeLibraryAndApp) - Multiple `.h` and `.cpp` files
- [CMakeCatch2](https://github.com/UCL/CMakeCatch2) - Includes Catch, example library (Eigen) and separate compilation of library and application
</details>
    
## Breakout session 1 

## Class Exercise 19

In this session you will be trying out the two types of dependency injection: constructor dependency injection and setter dependency injection. 

* Building on the `Student` class from homework 17 ([Solution](https://hackmd.io/c0qe_VL1Qk2tSfaYDkgkyw?view#Solution4)): 
   * Create a new `Laptop` class that has a string `os` data member for the operating system name and an integer  `year` data member for the year produced. 
   * `Laptop` should have both a default constructor that sets `year` to 0 and name to "Not set" as well as a constructor that takes two arguments to set `year` and  `os`
   * Modify `Student` to have a `std::unique_ptr` to a `Laptop` as a private data member
   * Implement the two types of dependency injection for the `Student` class: constructor, setter
   * Confirm that the `Student` class is now invarient to changes in how you instantiate `Laptop` 
* Discuss how and why you might implement an abstract interface class for the types of objects a Student owns 

_This exercise may spill over into breakout 2. Class exercise 20 is quicker_



#### Solution
<details>

You could use CMakeLibraryAndApp as a starting point.

The Laptop class should have multiple ways in which it can be constructed or configured. Here we just provide a default constructor (no arguments) and a constructor that allows `os` and `year` to be set. The `Laptop` class `Laptop.h` header file:
```cpp=
#ifndef Laptop_h
#define Laptop_h

#include <string>

class Laptop {
  public:
    Laptop();
    Laptop(const std::string& os, const int& year);
    ~Laptop();
    void SetOSYear(const std::string& os, const int& year);
    void Print();
  private:
    std::string os_;
    int year_;
};

#endif
```

`Laptop.cpp` implementation file:

```cpp=
#include "Laptop.h"
#include <iostream>

//--------------------------------------------------------------------
Laptop::Laptop()
{
  os_ = "Not set";
  year_ = 0;
  // do other stuff to setup  
}

//--------------------------------------------------------------------
Laptop::Laptop(const std::string& os, const int& year)
{
  os_ = os;
  year_ = year;
  // do other stuff to setup  
}

//--------------------------------------------------------------------
Laptop::~Laptop(){
  // do stuff to cleanup
}

//--------------------------------------------------------------------
void Laptop::SetOSYear(const std::string& os, const int& year)
{
  os_ = os;
  year_ = year;
}

//--------------------------------------------------------------------
void Laptop::Print()
{
  std::cout << os_ << " ("<< year_ << ")" << std::endl;
}
```

The `Student` class has a dependency on the `Laptop` class as has a data member pointing to a `Laptop` instance. We pass (inject) this dependency into the `Student` class. 

The Student class needs a constructor that accepts a pointer (we use a unique_ptr to avoid using raw pointers, see Week 3) to an already created Laptop instance to demonstrate constructor dependency injection. As well as a setter method to pass a Laptop pointer to demonstrate setter dependency injection. Student class `Student.h` header file:
```cpp=
#ifndef Student_h
#define Student_h

#include "Laptop.h"
#include <memory>
#include <string>

class Student {
  public:
    Student(std::string name, int age);
    Student(std::unique_ptr<Laptop> laptop, \
            std::string name, int age);
    ~Student();
    void SetLaptop(std::unique_ptr<Laptop> laptop);
    void Print();
    
  private:
    std::string name_;
    int age_;
    std::unique_ptr<Laptop> laptop_;
};

#endif
```

And the `Student.cpp` implementation file:

```cpp=
#include "Student.h"
#include <utility> // std::move
#include <iostream>

//--------------------------------------------------------------------
Student::Student(std::string name, int age)
{
  name_ = name;
  age_ = age;
  // do other stuff to setup  
}

//--------------------------------------------------------------------
Student::Student(std::unique_ptr<Laptop> laptop, std::string name, int age)
{
  laptop_ = std::move(laptop);
  name_ = name;
  age_ = age;
}

//--------------------------------------------------------------------
Student::~Student()
{
  // do stuff to cleanup
}

//--------------------------------------------------------------------
void Student::SetLaptop(std::unique_ptr<Laptop> laptop)
{
  laptop_.swap(laptop); 
//  laptop_ = std::move(laptop);
}

//--------------------------------------------------------------------
void Student::Print()
{
  std::cout << name_ << ", "<< age_ << ", ";
  if(laptop_){
    laptop_->Print();
  }
}
```

The following `myStudentApp.cpp` application then demonstrates the different types of dependency injection:
```cpp=
#include "Student.h"
#include "Laptop.h"
#include <memory>
#include <utility>

int main(){

  // Constructor dependency injection
  auto windows = std::make_unique<Laptop>("Windows 10 Home", 2020);
  Student juliet(std::move(windows), "Juliet", 101);
  juliet.Print();

  // Setter dependency injection
  auto mac = std::make_unique<Laptop>("OSX", 2019);
  Student john("John", 100);
  john.SetLaptop(std::move(mac)); // note move required as it is a unique_ptr
  john.Print();

  // Construct/configure Laptop differently
  auto ubuntu = std::make_unique<Laptop>();
  ubuntu->SetOSYear("Ubuntu 20.04", 2021);
  // No change to Student.cpp/.h required
  Student jerome(std::move(ubuntu), "Jerome", 102); // Constructor dependency injection 
  jerome.Print();

  return 0;
}
```

Example `CMakeLists.txt` lines for above if working from CMakeLibraryAndApp:
```cmake=
set (CMAKE_CXX_STANDARD 17)
add_library(Student Student.cpp)
add_library(Laptop Laptop.cpp)
add_executable(myStudentApp myStudentApp.cpp)
target_link_libraries(myStudentApp Student Laptop)
```

Main points for discussion: 
* If you used programming to interfaces and defined an abstract interface class `ResourceI` with methods like `virtual int GetYear() = 0;` and `virtual int GetName() = 0;` 
* You could then have concrete derived classes of different types of resources like `Laptop` and `Book` and `Video` stored in a container of `std::vector<std::unique_ptr<ResourceI> >` in the `Student` class. 
* And implement general methods in `Student` to add resources and print a summary of all resources, for example. 
* The implementation of `Student` would not need to be changed even you create new concrete derived types of `ResourceI`.

</details>

## Breakout session 2 

## Class Exercise 20

In this session you will implement a container class following the RAII (Resource Aquisition Is Initialisation) pattern: all resources aquired in the constructor and all resources released in the destrurctor. 

* Create a simple class `FooAllocator` that contains a data member that is a raw pointer `foo_ptr` to another class `Foo`
* Add a `std::cout` to the constructor and destructor of both classes so that you know when they have been called
* Create function `void AFunctionThatThrows()` that creates a `FooAllocator` object and then throws an exception before reaching the end of the fuction
    * Confirm that the destructor for both the `FooAllocator` and `Foo` objects are called as long as the exception is caught in the calling code
* Discuss how you would implement using`std::unique_ptr` instead of a raw pointer? 
    * i.e. how would the implementation differ if FooAllocator stored a `std::unique_ptr`? What if FooAllocator stored another type of resource, for example a `std::ofstream` for writing to files?

#### Solution
<details>

For simplicity implement in a single `myRAIIExample.cpp` application file:
```cpp=
#include <iostream>
#include <stdexcept>

using std::cout;
using std::endl;

// Dummy Foo class to indicate when constructed/destroyed
class Foo
{
  public:
    Foo(){ cout << "Foo()" << endl; }
    ~Foo(){ cout << "~Foo()" << endl;}
};

// FooAllocator implement RAII for a Foo
class FooAllocator
{
  public: 
    FooAllocator() // acquire resource in constructor
    { 
      cout << "FooAllocator()" << endl;
      foo_ptr_ = new Foo(); // just an example, in general use smart pointers and avoid new 
    }
    ~FooAllocator() // release resource in destructor
    { 
      cout << "~FooAllocator()" << endl;
      delete foo_ptr_;
    }

  private:
    Foo * foo_ptr_;
};

// A function that creats a FooAllocator and then throws exception
void FunctionThatThrows(){
  FooAllocator f;
  throw std::runtime_error("Something is wrong");
}

// Simple main to show the Foo's destructor is called
int main(){

  try {
    FunctionThatThrows();
  }
  catch (std::exception& e){
    std::cout << "Caught exception: "<< e.what() << std::endl;
  }
  
  return 0;
}
```
And then add the following to your CMakeLists.txt:
```cmake
add_executable(myRAIIExample myRAIIExample.cpp)
```

Main points for discussion:
* The FooAllocator implements similar behaviour to `std::unique_ptr` 
* If you were to store the `Foo` data member as a `std::unique_ptr<Foo>` in the FooAllocator or other class that owns it then you would not need to call the destructor `delete foo_ptr_` in ~FooAllocator 
* If the resource you are using implements RAII then no need to explicitly call destructor in class using it - this is the case for `std::ofstream`


    
</details>

  
## Breakout session 3 

In this session you'll try defining and instantiating some of your own function templates and class templates: trying out implicit vs explicit instantiation and working through an example where you provide a template specialisation for a specific type.

## Class Exercise 21

* Review the general syntax for a function template: `template <typename T> T sum(T a, T b);` 
* Then implement the `template <typename T> T sum(T a, T b);` example from the notes (slide number 31):
    * Try out both explicit and implicit instantiation 
    
#### Solution
<details>

The general form for a template function is 
`template < parameter-list > function-declaration`
   * The `template` keyword tells the compiler we are declaring or defining a template
   * The parameter list names the types that the template will use - you can use the `typename` or `class` keywords when defining a type although we recommend `typename` to avoid confusion with class definitions
   * An example template parameter would be`typename T1`. Here the name `T1` is arbitrary. You can think of it as an alias for a future type that will be supplied to the template function when it is instantiated
   * Then the `function-declaration` declares the function to be templated - this function can treat `T1` as if it is a type: it could manipulate variables of type T1, return a type T1, take type T1 variables as arguments

Take the `sum` function template from the Week 4 slides. The following should go in a header `.h` file and it defines a `sum` function and the logic to sum two inputs together based on a generic type `T` that will be supplied later on when the template is instantiated:
```cpp
template <typename T> // typename|class 
T sum (T a, T b)
{
  T result; 
  result = a + b; 
  return result;
}
```
which could then be instantiated in the main application as:
```cpp
double a = 1.5;
double b = 2.0;

// implicitly instantiates sum<double>(double a, double b)
std::cout << sum(a, b) << std::endl; // outputs 3.5

// explicitly instantiates sum<int>(static_cast<int>(a), static_cast<int>(b)) 
std::cout << sum<int>(a, b) << std::endl; // outputs 3
```
* Here we can see that the logic in the `sum` function can be reused for any variable or type as long as the `+` operator is defined for it
    
</details>

## Homework Exercise 22

_If there is time in the class can make a start on this_

Write a template function `TLists RemoveMatching(TElement element, TList l)` that searches a vector or list  for elements matching `element` and returns a new `TList` with those elements removed
* Try out both explicit and implicit instantiation
* Write a template specialisation for `RemoveMatching` for the case where `TElement` is a `char` and `TList` is a `std::string`
    
#### Solution
<details>

The following template definitions could go in a `RemoveMatching.h` header file that is then `#include RemoveMatching.h`'d in your main app:
```cpp
// Returns a new list with all matching elements removed
template<typename TElement, typename TList>
TList RemoveMatching(TElement match, TList list)
{
  TList new_list;
  for(auto element : list){
      if(element != match)
      {
          new_list.push_back(element);
      }
  }
  return new_list;
}

// For convenience also define a Print template function
template<typename T>
void Print(T array)
{
  for(auto entry : array)
  {
     std::cout << entry << " ";
  }
  std::cout << "\n";
}
```
Then some examples of how to instantiate the function template are:
```cpp
std::vector<int> v{1,20,40,50};

// Implicit instantiation
auto v2 = RemoveMatching(20, v);
Print(v2); // outputs: 1 40 50

// Explicit instantiation
auto v3 = RemoveMatching<int, std::vector<int>>(40, v);
print(v3); // outputs: 1 20 50

std::list<std::string> l{"A","BB","CCC","DDD"};

// Implicit instantiation
auto l2 = RemoveMatching("CCC", l);
Print(l2); // outputs A BB DDD

// Explicit instantiation for std::list but now try to pass
// it a vector of int's - the following will not compile 
// auto l3 = RemoveMatching<std::string, std::list<std::string> >(20, v);
```
    
</details>

## Class Exercise 23

* Review the general syntax for a class template: 
`template < parameter-list > class-declaration`
* Implement the `MyPair` class template from the week 4 slides 
* Try using with both Implicit and Explicit instantiation

#### Solution
<details>

Compare the general syntax for a class template:
`template < parameter-list > class-decaration`
to the specific `MyPair` example from the notes (Week 4, slide number 45):

In `pairClassExample.h`
```cpp
template <typename T> 
class MyPair 
{ 
  T m_Values[2];

  public:
    MyPair(const T &first, const T &second); T getMax() const;
};
#include "pairClassExample.cc" // include .cc file in header file just for templates 
```
* Note the similarities with the function template syntax: `template < parameter-list >` followed by function or class declaration.

Then in `pairClassExample.cc`
```cpp
template <typename T>
MyPair<T>::MyPair(const T& first, const T& second) 
{
  m_Values[0] = first;
  m_Values[1] = second; 
}

template <typename T>
T MyPair<T>::getMax() const 
{
  if (m_Values[0] > m_Values[1])
    return m_Values[0];
  else 
    return m_Values[1];
}
```

Then in the main app:
```cpp
  // Explicit instantiation
  MyPair<int> a(1,2);
  std::cout << "Max is:" << a.getMax() << std::endl;
  // outputs 2.0

  // Implicit instantiation
  MyPair b(3.0, 4.5);
  std::cout << "Max is:" << b.getMax() << std::endl;
  // outputs 4.5
  
  // Explicit <int> but now passing double that get static_cast 
  MyPair<int> c(1.9,2.9);
  std::cout << "Max is:" << c.getMax() << std::endl; 
  // outputs 2
```
    
</details>

### Homework Exercise - 24

Extend the MyPair class with two new methods:
* A `void printValues()` method that prints to screen the typeid of the class T which for which the template has been instantiated as well as the values of m_Values[0] and m_Values[1]
* A `void swapValues()` method that uses `std::swap` to swap the elements
    
#### Solution
<details>

The `pairClassExample.h` would have the following methods declarations added:
``` cpp
template <typename T> 
class MyPair 
{ 
  T m_Values[2];

  public:
    MyPair(const T &first, const T &second); 
    T getMax() const;
    void swapValues();
    void printValues();
};
#include "pairClassExample.cc"
```
and `pairClassExample.cc` has the following definitions added:
```cpp=
template <typename T>
void MyPair<T>::swapValues()
{
  std::swap(m_Values[0], m_Values[1]);
}

template <typename T>
void MyPair<T>::printValues()
{
  std::cout << typeid(T).name() << ": " << m_Values[0] << " " << m_Values[1] << std::endl;
}
```
then in the main function you could check with:
```cpp
  MyPair b(3.0, 4.5);
  b.printValues(); // outputs "d: 3 4.5"

  MyPair<int> c(1.9,2.9);
  c.printValues(); // outputs "i: 1 2
  c.swapValues(); 
  c.printValues(); // outputs "i: 2 1"
```
    
</details>
    
# Questions

Here you can post any question you have while we are going through this document. A summary of the questions and the answers will be posted in moodle after each session. Please, use a new bullet point for each question and sub-bullet points for their answers.

For example writing like this:
```
- Example question
  - [name=student_a] Example answer
  - [name=TA_1] Example answer
```
produces the following result:
- Example question
  - [name=student_a] Example answer
  - [name=TA_1] Example answer

Write new questions below :point_down: 

  - []
  - [name=TA_1] Example answer




###### tags: `phas0100` `teaching` `class`