preprocessor: remove introduction to C++ programming
parent
49d7e08710
commit
d1377c3838
448
preprocessor.tex
448
preprocessor.tex
|
@ -56,454 +56,6 @@
|
|||
\tableofcontents
|
||||
\end{frame}
|
||||
|
||||
\section{Introduction to object-oriented programming in C++}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Object-oriented programming (OOP)}
|
||||
\begin{itemize}
|
||||
\item Traditional way of programming: a program is a list of instructions (organized in functions) which manipulate data
|
||||
\item OOP is an alternative programming paradigm that uses \alert{objects} and their interactions to design programs
|
||||
\pause
|
||||
\item With OOP, programming becomes a kind of modelization: each object of the program should modelize a real world object, or a mathematical object (\textit{e.g.} a matrix, an equation, a model...)
|
||||
\item Each object can be viewed as an independent little machine with a distinct role or responsibility
|
||||
\item Each object is capable of receiving messages, processing data, and sending messages to other objects
|
||||
\pause
|
||||
\item Main advantage of OOP is \alert{modularity}, which leads to greater reusability, flexibility and maintainability
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Object}
|
||||
\framesubtitle{Definition and example}
|
||||
\begin{itemize}
|
||||
\item An \alert{object} is the bundle of:
|
||||
\begin{itemize}
|
||||
\item several variables (called its \alert{attributes}), which modelize the characteristics (or the state) of the object
|
||||
\item several functions (called its \alert{methods}) which operate on the attributes, and which modelize the behaviour of the object (the actions it can perform)
|
||||
\end{itemize}
|
||||
\pause
|
||||
\item Example: suppose we want to modelize a coffee machine
|
||||
\begin{itemize}
|
||||
\item The coffee machine (in real life) is a box, with an internal counter for the credit balance, a slot to put coins in, and a button to get a coffee
|
||||
\item The corresponding object will have one attribute (the current credit balance) and two methods (one which modelizes the introduction of money, and the other the making of a coffee)
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]
|
||||
\frametitle{A coffee machine}
|
||||
\framesubtitle{Class definition}
|
||||
\begin{block}{C++ header file (\texttt{CoffeeMachine.hh})}
|
||||
\begin{scriptsize}
|
||||
\begin{verbatim}
|
||||
class CoffeeMachine {
|
||||
public:
|
||||
int credit;
|
||||
CoffeeMachine();
|
||||
void put_coin(int coin_value);
|
||||
void get_coffee();
|
||||
};
|
||||
\end{verbatim}
|
||||
\end{scriptsize}
|
||||
\end{block}
|
||||
\begin{itemize}
|
||||
\item A \alert{class} is a template (or a blueprint) of an object
|
||||
\item Collectively, the attributes and methods defined by a class are called \alert{members}
|
||||
\item A class definition creates a new \alert{type} (\texttt{CoffeeMachine}) that can be used like other C++ types (\textit{e.g.} \texttt{int}, \texttt{string}, ...)
|
||||
\item In C++, class definitions are put in header files (\texttt{.hh} extension)
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]
|
||||
\frametitle{A coffee machine}
|
||||
\framesubtitle{Method bodies}
|
||||
\begin{block}{C++ source file (\texttt{CoffeeMachine.cc})}
|
||||
\begin{scriptsize}
|
||||
\begin{verbatim}
|
||||
void CoffeeMachine::put_coin(int coin_value)
|
||||
{
|
||||
credit += coin_value;
|
||||
cout << "Credit is now " << credit << endl;
|
||||
}
|
||||
|
||||
void CoffeeMachine::get_coffee()
|
||||
{
|
||||
if (credit == 0)
|
||||
cout << "No credit!" << endl;
|
||||
else {
|
||||
credit--;
|
||||
cout << "Your coffee is ready, credit is now " << credit << endl;
|
||||
}
|
||||
}
|
||||
\end{verbatim}
|
||||
\end{scriptsize}
|
||||
\end{block}
|
||||
\begin{itemize}
|
||||
\item Methods can refer to other members (here the two methods modify the \texttt{credit} attribute)
|
||||
\item Method bodies are put in source files (\texttt{.cc} extension)
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]
|
||||
\frametitle{Constructors and destructors}
|
||||
\begin{itemize}
|
||||
\item In our class header, there is a special method called \texttt{CoffeeMachine()} (same name than the class)
|
||||
\item It is a \alert{constructor}: called when the object is created, used to initalize the attributes of the class
|
||||
\end{itemize}
|
||||
\begin{block}{C++ source file (\texttt{CoffeeMachine.cc}, continued)}
|
||||
\begin{scriptsize}
|
||||
\begin{verbatim}
|
||||
CoffeeMachine::CoffeeMachine()
|
||||
{
|
||||
credit = 0;
|
||||
}
|
||||
\end{verbatim}
|
||||
\end{scriptsize}
|
||||
\end{block}
|
||||
\begin{itemize}
|
||||
\item It is possible to create constructors with arguments
|
||||
\item It is also possible to define a \alert{destructor} (method name is the class name prepended by a tilde, like \texttt{$\sim$CoffeeMachine}): called when the object is destroyed, used to do cleaning tasks (\textit{e.g.} freeing memory)
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
|
||||
\begin{frame}[fragile]
|
||||
\frametitle{Instantiation and method invocation}
|
||||
\begin{block}{Program main function}
|
||||
\begin{scriptsize}
|
||||
\begin{verbatim}
|
||||
#include "CoffeeMachine.hh"
|
||||
|
||||
int main()
|
||||
{
|
||||
CoffeeMachine A, B;
|
||||
|
||||
A.put_coin(2);
|
||||
A.get_coffee();
|
||||
|
||||
B.put_coin(1);
|
||||
B.get_coffee();
|
||||
B.get_coffee();
|
||||
}
|
||||
\end{verbatim}
|
||||
\end{scriptsize}
|
||||
\end{block}
|
||||
\begin{itemize}
|
||||
\item Creates two machines: at the end, \texttt{A} has 1 credit, \texttt{B} has no credit and refused last coffee
|
||||
\item \texttt{A} and \texttt{B} are called \alert{instances} of class \texttt{CoffeeMachine}
|
||||
\item Methods are invoked by appending a dot and the method name to the instance variable name
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]
|
||||
\frametitle{Dynamic instantiation with \texttt{new}}
|
||||
\begin{block}{Program main function}
|
||||
\begin{scriptsize}
|
||||
\begin{verbatim}
|
||||
#include "CoffeeMachine.hh"
|
||||
|
||||
void main()
|
||||
{
|
||||
CoffeeMachine *A;
|
||||
|
||||
A = new CoffeeMachine();
|
||||
|
||||
A->put_coin(2);
|
||||
A->get_coffee();
|
||||
|
||||
delete A;
|
||||
}
|
||||
\end{verbatim}
|
||||
\end{scriptsize}
|
||||
\end{block}
|
||||
\begin{itemize}
|
||||
\item Here \texttt{A} is a pointer to an instance of class \texttt{CoffeeMachine}
|
||||
\item Dynamic creation of instances is done with \texttt{new}, dynamic deletion with \texttt{delete} (analogous to \texttt{malloc} and \texttt{free})
|
||||
\item Since \texttt{A} is a pointer, methods are called with \texttt{->} instead of a dot
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]
|
||||
\frametitle{Access modifiers}
|
||||
\begin{itemize}
|
||||
\item In our coffee machine example, all attributes and methods were marked as \texttt{public}
|
||||
\item Means that those attributes and methods can be accessed from anywhere in the program
|
||||
\item Here, one can gain credit without putting money in the machine, with something like \texttt{A.credit = 1000;}
|
||||
\item The solution is to declare it \alert{private}: such members can only be accessed from methods within the class
|
||||
\end{itemize}
|
||||
\begin{block}{C++ header file (\texttt{CoffeeMachine.hh})}
|
||||
\begin{scriptsize}
|
||||
\begin{verbatim}
|
||||
class CoffeeMachine {
|
||||
private:
|
||||
int credit;
|
||||
public:
|
||||
CoffeeMachine();
|
||||
void put_coin(int coin_value);
|
||||
void get_coffee();
|
||||
};
|
||||
\end{verbatim}
|
||||
\end{scriptsize}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Interface}
|
||||
\begin{itemize}
|
||||
\item The public members of a class form its \alert{interface}: they describe how the class interacts with its environment
|
||||
\item Seen from outside, an object is a ``black box'', receiving and sending messages through its interface
|
||||
\item Particular attention should be given to the interface design: an external programmer should be able to work with an class by only studying its interface, but not its internals
|
||||
\item A good design pratice is to limit the set of public members to the strict minimum:
|
||||
\begin{itemize}
|
||||
\item enhances code understandability by making clear the interface
|
||||
\item limits the risk that an internal change in the object requires a change in the rest of the program: \alert{loose coupling}
|
||||
\item prevents the disruption of the coherence of the object by an external action: principle of \alert{isolation}
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Why isolation is important}
|
||||
\begin{itemize}
|
||||
\item Consider a class \texttt{Circle} with the following attributes:
|
||||
\begin{itemize}
|
||||
\item coordinates of the center
|
||||
\item radius
|
||||
\item surface
|
||||
\end{itemize}
|
||||
\item If all members are public, it is possible to modify the radius but not the surface, therefore disrupting internal coherence
|
||||
\item The solution is to make radius and surface private, and to create a public method \texttt{changeRadius} which modifies both simultaneously
|
||||
\item \textit{Conclusion:} Creating a clear interface and isolating the rest diminishes the risk of introducing bugs
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]
|
||||
\frametitle{Inheritance (1/2)}
|
||||
|
||||
\begin{block}{Matrices and positive definite matrices}
|
||||
\begin{scriptsize}
|
||||
\begin{columns}[t]
|
||||
\begin{column}{4.8cm}
|
||||
\begin{verbatim}
|
||||
class Matrix
|
||||
{
|
||||
protected:
|
||||
int height, width;
|
||||
double[] elements;
|
||||
public:
|
||||
Matrix(int n, int p,
|
||||
double[] e);
|
||||
virtual ~Matrix();
|
||||
double det();
|
||||
};
|
||||
\end{verbatim}
|
||||
\end{column}
|
||||
\begin{column}{6cm}
|
||||
\begin{verbatim}
|
||||
class PositDefMatrix : public Matrix
|
||||
{
|
||||
public:
|
||||
PositDefMatrix(int n, int p,
|
||||
double[] e);
|
||||
Matrix cholesky();
|
||||
};
|
||||
\end{verbatim}
|
||||
\end{column}
|
||||
\end{columns}
|
||||
\end{scriptsize}
|
||||
|
||||
\end{block}
|
||||
\begin{itemize}
|
||||
\item \texttt{PositDefMatrix} is a \alert{subclass} (or \alert{derived class}) of \texttt{Matrix}
|
||||
\item Conversely \texttt{Matrix} is the \alert{superclass} of \texttt{PositDefMatrix}
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Inheritance (2/2)}
|
||||
\begin{itemize}
|
||||
\item \texttt{PositDefMatrix} inherits \texttt{width}, \texttt{height}, \texttt{elements} and \texttt{det} from \texttt{Matrix}
|
||||
\item Method \texttt{cholesky} can be called on an instance of \texttt{PositDefMatrix}, but not of \texttt{Matrix}
|
||||
\item The keyword \texttt{protected} means: public for subclasses, but private for other classes
|
||||
\item \alert{Type casts} are legal when going upward in the derivation tree:
|
||||
\begin{itemize}
|
||||
\item a pointer to \texttt{PositDefMatrix} can be safely cast to a \texttt{Matrix*}
|
||||
\item the converse is faulty and leads to unpredictable results
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]
|
||||
\frametitle{Constructors and destructors (bis)}
|
||||
\begin{block}{C++ code snippet}
|
||||
\begin{scriptsize}
|
||||
\begin{verbatim}
|
||||
Matrix::Matrix(int n, int p, double[] e) : height(n), width(p)
|
||||
{
|
||||
elements = new double[n*p];
|
||||
memcpy(elements, e, n*p*sizeof(double));
|
||||
}
|
||||
|
||||
Matrix::~Matrix()
|
||||
{
|
||||
delete[] elements;
|
||||
}
|
||||
|
||||
PositDefMatrix::PositDefMatrix(int n, int p, double[] e) :
|
||||
Matrix(n, p, e)
|
||||
{
|
||||
// Check that matrix is really positive definite
|
||||
}
|
||||
\end{verbatim}
|
||||
\end{scriptsize}
|
||||
\end{block}
|
||||
\begin{itemize}
|
||||
\item Constructor of \texttt{PositDefMatrix} calls constructor of \texttt{Matrix}
|
||||
\item Note the abbreviated syntax with colon
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Possible derivation tree for real matrices}
|
||||
\framesubtitle{Arrow means \textit{...is a subclass of...}}
|
||||
\begin{center}
|
||||
\includegraphics[width=10cm]{matrices.png}
|
||||
\end{center}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Polymorphism (1/3)}
|
||||
\begin{itemize}
|
||||
\item In previous example, determinant computation method uses the same algorithm for both classes
|
||||
\item But for positive definite matrices, a faster algorithm exists (using the cholesky)
|
||||
\item \alert{Polymorphism} offers an elegant solution:
|
||||
\begin{itemize}
|
||||
\item declare \texttt{det} as a \alert{virtual method} in class \texttt{Matrix}
|
||||
\item \alert{override} it in \texttt{PositDefMatrix}, and provide the corresponding implementation
|
||||
\end{itemize}
|
||||
\item When method \texttt{det} will be invoked, the correct implementation will be selected, depending on the type of the instance (this is done through a runtime type test)
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]
|
||||
\frametitle{Polymorphism (2/3)}
|
||||
|
||||
\begin{block}{Class headers}
|
||||
\begin{scriptsize}
|
||||
\begin{columns}[t]
|
||||
\begin{column}{4.8cm}
|
||||
\begin{verbatim}
|
||||
class Matrix
|
||||
{
|
||||
protected:
|
||||
int height, width;
|
||||
double[] elements;
|
||||
public:
|
||||
Matrix(int n, int p,
|
||||
double[] e);
|
||||
virtual ~Matrix();
|
||||
virtual double det();
|
||||
bool is_invertible();
|
||||
};
|
||||
\end{verbatim}
|
||||
\end{column}
|
||||
\begin{column}{6cm}
|
||||
\begin{verbatim}
|
||||
class PositDefMatrix : public Matrix
|
||||
{
|
||||
public:
|
||||
PositDefMatrix(int n, int p,
|
||||
double[] e);
|
||||
Matrix cholesky();
|
||||
virtual double det();
|
||||
};
|
||||
\end{verbatim}
|
||||
\end{column}
|
||||
\end{columns}
|
||||
\end{scriptsize}
|
||||
|
||||
\end{block}
|
||||
\begin{itemize}
|
||||
\item Note the \texttt{virtual} keyword
|
||||
\item A method has been added to determine if matrix is invertible
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]
|
||||
\frametitle{Polymorphism (3/3)}
|
||||
\begin{block}{C++ code snippet}
|
||||
\begin{scriptsize}
|
||||
\begin{verbatim}
|
||||
bool Matrix::is_invertible()
|
||||
{
|
||||
return(det() != 0);
|
||||
}
|
||||
|
||||
double PositDefMatrix::det()
|
||||
{
|
||||
// Square product of diagonal terms of cholesky decomposition
|
||||
}
|
||||
\end{verbatim}
|
||||
\end{scriptsize}
|
||||
\end{block}
|
||||
\begin{itemize}
|
||||
\item A call to \texttt{is\_invertible} on a instance of \texttt{Matrix} will use the generic determinant computation
|
||||
\item The same call on an instance of \texttt{PositDefMatrix} will call the specialized determinant computation
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Abstract classes}
|
||||
\begin{itemize}
|
||||
\item It is possible to create classes which don't provide an implementation for some virtual methods
|
||||
\item Syntax in the header: \\
|
||||
\texttt{virtual int method\_name() = 0;}
|
||||
\item As a consequence, such classes can never be instantiated
|
||||
\item Generally used as the root of a derivation tree, when classes of the tree share behaviours but not implementations
|
||||
\item Such classes are called \alert{abstract classes}
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Some programming rules (1/2)}
|
||||
\begin{itemize}
|
||||
\item Don't repeat yourself (DRY): if several functions contain similar portions of code, \alert{factorize} that code into a new function
|
||||
\begin{itemize}
|
||||
\item makes code shorter
|
||||
\item reduces the risk of introducing inconsistencies
|
||||
\item makes easier the propagation of enhancements and bug corrections
|
||||
\end{itemize}
|
||||
\item Make short functions
|
||||
\begin{itemize}
|
||||
\item often difficult to grasp what a long function does
|
||||
\item structuring the code by dividing it into short functions makes the logical structure more apparent
|
||||
\item enhances code readability and maintainability
|
||||
\end{itemize}
|
||||
\item Use explicit variable names (except for loop indexes)
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Some programming rules (2/2)}
|
||||
\begin{itemize}
|
||||
\item Global variables are evil
|
||||
\begin{itemize}
|
||||
\item a global variable can be modified from anywhere in the code (nonlocality problem)
|
||||
\item creates a potentially unlimited number of dependencies between all portions of the code
|
||||
\item makes bugs difficult to localize (any part of the code could have created the trouble)
|
||||
\item to summarize, goes against the principle of modularity
|
||||
\item in addition, global variables are not thread safe (unless used with locks/mutexes)
|
||||
\end{itemize}
|
||||
\item Document your code when it doesn't speak by itself
|
||||
\begin{itemize}
|
||||
\item Dynare preprocessor code is documented using Doxygen
|
||||
\item done through special comments beginning with an exclamation mark
|
||||
\item run \texttt{doxygen} from the source directory to create a bunch of HTML files documenting the code
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\section{Parsing}
|
||||
|
||||
\begin{frame}
|
||||
|
|
Loading…
Reference in New Issue