diff --git a/pages/CSE332S/CSE332S_L8.md b/pages/CSE332S/CSE332S_L8.md index 1154860..b1d9c20 100644 --- a/pages/CSE332S/CSE332S_L8.md +++ b/pages/CSE332S/CSE332S_L8.md @@ -2,4 +2,235 @@ ## From procedural to object-oriented programming +Procedural programming + +- Focused on **functions** and the call stack +- Data and functions treated as **separate** abstractions +- Data must be passed into/returned out of functions, functions work on any piece of data that can be passed in via parameters + +Object-oriented programming + +- Data and functions packaged **together** into a single abstraction +- Data becomes more interesting (adds behavior) +- Functions become more focused (restricts data scope) + +## Object-oriented programming + +- Data and functions packaged together into a single abstraction + - Data becomes more interesting (adds behavior) + - Functions become more focused (restricts data scope) + +### Today: + +- An introduction to classes and structs + - Member variables (state of an object) + - Constructors + - Member functions/operators (behaviors) + - Encapsulation + - Abstraction + +At a later date: + +- Inheritance (class 12) +- Polymorphism (12) +- Developing reusable OO designs (16-21) + +## Class and struct + +### From C++ Functions to C++ Structs/Classes + +C++ functions encapsulate behavior + +- Data used/modified by a function must be passed in via parameters +- Data produced by a function must be passed out via return type + +Classes (and structs) encapsulate related data and behavior (**Encapsulation**) + +- Member variables maintain each object’s state +- Member functions (methods) and operators have direct access to member variables of the object on which they are called +- Access to state of an object is often restricted +- **Abstraction** - a class presents only the relevant details of an object, through its public interface. + +### C++ Structs vs. C++ Classes? + +Class members are **private** by default, struct members are **public** by default + +When to use a struct + +- Use a struct for things that are mostly about the data +- **Add constructors and operators to work with STL containers/algorithms** + +When to use a class + +- Use a class for things where the behavior is the most important part +- Prefer classes when dealing with encapsulation/polymorphism (later) + +```cpp +// point2d.h - struct declaration +struct Point2D { + Point2D(int x, int y); + bool operator< (const Point2D &) const; // a const member function + int x_; // promise a member variable + int y_; +}; +``` + +```cpp +// point2d.cpp - methods functions +#include "point2d.h" + +Point2D::Point2D(int x, int y) : +x_(x), y_(y) {} + +bool Point2D::operator< (const Point2D &other) const { + return x_ < other.x_ || (x_ == other.x_ && y_ < other.y_); +} +``` + +### Structure of a class + +```cpp +class Date { + public: // public stores the member functions and variables accessible to the outside of class + Date(); // default constructor + Date (const Date &); // copy constructor + Date(int year, int month, int day); // constructor with parameters + virtual ~Date(); // (virtual) destructor + Date& operator= (const Date &); // assignment operator + int year() const; // accessor + int month() const; // accessor + int day() const; // accessor + void year(int year); // mutator + void month(int month); // mutator + void day(int day); // mutator + string yyymmdd() const; // generate a string representation of the date + private: // private stores the member variables that only the class can access + int year_; + int month_; + int day_; +}; +``` + +#### Class constructor + +- Same name as its class +- Establishes invariants for objects of the class +- **Base class/struct and member initialization list** + - Used to initialize member variables + - Used to construct base class when using inheritance + - Must initialize const and reference members there + - **Runs before the constructor body, object is fully initialized in constructor body** + +```cpp +// date.h +class Date { + public: + Date(); + Date(const Date &); + Date(int year, int month, int day); + ~Date(); + // ... + private: + int year_; + int month_; + int day_; +}; +``` + +```cpp +// date.cpp +Date::Date() : year_(0), month_(0), day_(0) {} // initialize member variables, use pre-defined values as default values +Date::Date(const Date &other) : year_(other.year_), month_(other.month_), day_(other.day_) {} // copy constructor +Date::Date(int year, int month, int day) : year_(year), month_(month), day_(day) {} // constructor with parameters +// ... +``` + +#### More on constructors + +Compiler defined constructors: + +- Compiler only defines a default constructor if no other constructor is declared +- Compiler defined constructors simply construct each member variable using the same operation + +Default constructor for **built-in types** does nothing (leaves the variable uninitialized)! + +It is an error to read an uninitialized variable + +## Access control and friend declarations + +Declaring access control scopes within a class - where is the member visible? + +- `private`: visible only within the class +- `protected`: also visible within derived classes (more later) +- `public`: visible everywhere + +Access control in a **class** is `private` by default + +- It’s better style to label access control explicitly + +A `struct` is the same as a `class`, except access control for a `struct` is `public` by default + +- Usually used for things that are “mostly data” + +### Issues with Encapsulation in C++ + +Encapsulation - state of an object is kept internally (private), state of an object can be changed via calls to its public interface (public member functions/operators) + +Sometimes two classes are closely tied: + +- One may need direct access to the other’s internal state +- But, other classes should not have the same direct access +- Containers and iterators are an example of this + +We could: + +1. Make the internal state public, but this violates **encapsulation** +2. Use an inheritance relationship and make the internal state protected, but the inheritance relationship doesn’t make sense +3. Create fine-grained accessors and mutators, but this clutters the interface and violates **abstraction** + +### Friend declarations + +Offer a limited way to open up class encapsulation + +C++ allows a class to declare its “friends” + +- Give access to specific classes or functions + +Properties of the friend relation in C++ + +- Friendship gives complete access + - Friend methods/functions behave like class members + - public, protected, private scopes are all accessible by friends +- Friendship is asymmetric and voluntary + - A class gets to say what friends it has (giving permission to them) + - But one cannot “force friendship” on a class from outside it +- Friendship is not inherited + - Specific friend relationships must be declared by each class + - “Your parents’ friends are not necessarily your friends” + + +```cpp +// in Foo.h +class Foo { + friend ostream &operator<< (ostream &out, const Foo &f); // declare a friend function, can be added at any line of the class declaration + public: + Foo(int x); + ~Foo(); + // ... + private: + int baz_; +}; + +ostream &operator<< (ostream &out, const Foo &f); +``` + +```cpp +// in Foo.cpp +ostream &operator<< (ostream &out, const Foo &f) { + out << f.baz_; // access private member variable via friend declaration + return out; +} + + +``` diff --git a/pages/Math416/Math416_L4.md b/pages/Math416/Math416_L4.md index 03be436..39d2386 100644 --- a/pages/Math416/Math416_L4.md +++ b/pages/Math416/Math416_L4.md @@ -146,21 +146,50 @@ EOP #### Theorem of differentiability -Let $f:G\to \mathbb{C}$ be holomorphic function on open set $G\subset \mathbb{C}$ and real differentiable. $f=u+iv$ where $u,v$ are real differentiable functions. +Let $f:G\to \mathbb{C}$ be a function defined on an open set $G\subset \mathbb{C}$ that is both holomorphic and (real) differentiable, where $f=u+iv$ with $u,v$ real differentiable functions. -Then, $f$ is conformal if and only if $f$ is holomorphic at $\zeta_0$ and $f'(\zeta_0)\neq 0,\forall \zeta_0\in G$. +Then, $f$ is conformal at every point $\zeta_0\in G$ if and only if $f$ is holomorphic at $\zeta_0$ and $f'(\zeta_0)\neq 0$. Proof: - +We prove the equivalence in two parts. -Case 1: Suppose $f(\zeta)=a\zeta+b\overline{\zeta}$, Let $b=\frac{\partial f}{\partial \overline{z}}(\zeta)$. We need to prove $a+b\neq 0$. So we want $b=0$ and $a\neq 0$, other wise $f(\mathbb{R})=0$. +($\implies$) Suppose that $f$ is conformal at $\zeta_0$. By definition, conformality means that $f$ preserves angles (including their orientation) between any two intersecting curves through $\zeta_0$. In the language of real analysis, this requires that the (real) derivative (Jacobian) of $f$ at $\zeta_0$, $Df(\zeta_0)$, acts as a similarity transformation. Any similarity in $\mathbb{R}^2$ can be written as a rotation combined with a scaling; in particular, its matrix representation has the form +$$ +\begin{pmatrix} +A & -B \\ +B & A +\end{pmatrix}, +$$ +for some real numbers $A$ and $B$. This is exactly the matrix corresponding to multiplication by the complex number $a=A+iB$. Therefore, the Cauchy-Riemann equations must hold at $\zeta_0$, implying that $f$ is holomorphic at $\zeta_0$. Moreover, because the transformation is nondegenerate (preserving angles implies nonzero scaling), we must have $f'(\zeta_0)=a\neq 0$. -$f:\mathbb{R}\to \{(a+b)t\}$ is not conformal. +($\impliedby$) Now suppose that $f$ is holomorphic at $\zeta_0$ and $f'(\zeta_0)\neq 0$. Then by the definition of the complex derivative, the first-order (linear) approximation of $f$ near $\zeta_0$ is +$$ +f(\zeta_0+h)=f(\zeta_0)+f'(\zeta_0)h+o(|h|), +$$ +for small $h\in\mathbb{C}$. Multiplication by the nonzero complex number $f'(\zeta_0)$ is exactly a rotation and scaling (i.e., a similarity transformation). Therefore, for any smooth curve $\gamma(t)$ with $\gamma(t_0)=\zeta_0$, we have +$$ +(f\circ\gamma)'(t_0)=f'(\zeta_0)\gamma'(t_0), +$$ +and the angle between any two tangent vectors at $\zeta_0$ is preserved (up to the fixed rotation). Hence, $f$ is conformal at $\zeta_0$. -... +For further illustration, consider the special case when $f$ is an affine map. -Case 2: Immediate consequence of the lemma of conformal function. +Case 1: Suppose +$$ +f(\zeta)=a\zeta+b\overline{\zeta}. +$$ +The Wirtinger derivatives of $f$ are +$$ +\frac{\partial f}{\partial \zeta}=a \quad \text{and} \quad \frac{\partial f}{\partial \overline{\zeta}}=b. +$$ +For $f$ to be holomorphic, we require $\frac{\partial f}{\partial \overline{\zeta}}=b=0$. Moreover, to have a nondegenerate (angle-preserving) map, we must have $a\neq 0$. If $b\neq 0$, then the map mixes $\zeta$ and $\overline{\zeta}$, and one can check that the linearization maps the real axis $\mathbb{R}$ into the set $\{(a+b)t\}$, which does not uniformly scale and rotate all directions. Thus, $f$ fails to be conformal when $b\neq 0$. + +Case 2: For a general holomorphic function, the lemma of conformal functions shows that if +$$ +(f\circ \gamma)'(t_0)=f'(\zeta_0)\gamma'(t_0) +$$ +for any differentiable curve $\gamma$ through $\zeta_0$, then the effect of $f$ near $\zeta_0$ is exactly given by multiplication by $f'(\zeta_0)$. Since multiplication by a nonzero complex number is a similarity transformation, $f$ is conformal at $\zeta_0$. EOP