Recall: observer pattern

<aside> 💡 Decorator Pattern

eg. Windowing system

</aside>

Componenet

ConcreteComponent

Decorators

eg. Window w/ scrollbar is a kind of window and has a ptr to the underlying plain window

Window w/ scrollbar & menu is a window, has a ptr to window w/ scrollbar, which has a ptr to window

eg. Pizza

IMG_3070.heic

IMG_3071.heic

class Pizza {
 public:
	virtual float price() const = 0;
	virtual desc() const = 0;
	virtual ~Pizza(){}	
};
class CrustAndSource:public Pizza {
 public:
	float price() const override {return 5.99;}
	string desc() const override {return "Pizza";}
};
class Decorator:public Pizza {
 protected:
	Pizza *component;
 public:
	Decorator(Pizza *p):component{p}{}
	virtual ~Decorator() {delete component;}
};
class StuffedCrust:public Decorator {
 public:
	StuffedCrust(Pizza *p): Decorator{p}{}
	float price() const override {return component->price() + 2.69;}
	string desc() const override {return component->desc() + "with stuffed crust";}
};
class Topping:public Decorator {
	string theTopping;
 public:
	...//exercise
};

Use:

Pizza *p1 = new CrustAndSource;
p1 = new Topping{p1, "cheese"};
p1 = new Topping{p1, "mushrooms"};
p1 = new StuffedCrust{p1};
cout << p1->desc() << ' ' 
	<< p1->price() << endl;
delete p1;

check: 25-decorator

<aside> 💡 v[i] - ith element of v

v.at() - checked version of v[i]

Problem:

C’s solution: f’ns return a status code or sets the global variable error

<aside> 💡 Exception

C++’s solution - when an error condition arises,

But we can write handlers to catch errs & deal with them

<aside> 💡 vector<T>:: at throws an exn of type std::out.of.range when it fails

</aside>

</aside>

We can handle it as follows ↓

import <stdexcept>;
...
try {
	cout << v.at(10000); // statements that many throw go in a try block
}
catch(out.of.range r) {
	cerr << "Range error," << r.what() << endl;
}

Now consider:

void f() {// ↓ class   ↓ what .what() will say
	throw out.of.range {"f"};
}
void g() { f(); }
void h() { g(); }
int main() {
	try { h(); }
	catch(out.of.range) {...}
}

What happens?

main calls h
h calls g
g calls f
f throws out.of.range

Control goes back through the call chain (unwinding the stack) until a handler is found

No matching handler in the entire call chain → program teminates

A handler might do part of the recovery job, i.e. execute some corrective code & throw another exn