\documentclass[a4paper,12pt]{article}

\usepackage[latin2]{inputenc}

\title{Vaje 23}
\author{Simona Perčič}
\date{4.5.}

\begin{document}

\maketitle

\section*{Polimorfizem}

Predmeti iz razreda skladov imajo lastnost, da lahko na njih:
%
\begin{itemize}
\item nalagamo predmete in
\item z njih zlagamo predmete.
\end{itemize}

Primeri so:
%
\begin{itemize}
\item razred skladov celih števil:
  \begin{itemize}
  \item \texttt{Nalozi(int elem)} naloži element na sklad
  \item \texttt{int Zlozi()} vzame zgornji element iz sklada in ga
    vrne
  \end{itemize}
\item razred skladov racionalnih števil:
  \begin{itemize}
  \item \texttt{Nalozi(float elem)} naloži element na sklad
  \item \texttt{float Zlozi()} vzame zgornji element iz sklada in ga
    vrne
  \end{itemize}
\item razred skladov znakov:
  \begin{itemize}
  \item \texttt{Nalozi(char elem)} naloži element na sklad
  \item \texttt{char Zlozi()} vzame zgornji element iz sklada in ga
    vrne
  \end{itemize}
\item razred skladov elementov tipa \texttt{tSklElt}:
  \begin{itemize}
  \item \texttt{Nalozi(tSklElt elem)} naloži element na sklad
  \item \texttt{tSklElt Zlozi()} vzame zgornji element iz sklada in ga
    vrne
  \end{itemize}
\end{itemize}

Ogledali smo si iste operacije, vendar za sklade predmetov različnimi
tipov.  Sedaj bomo uporabili princip polimorfizma in sicer tako, da se
bomo znebili skladov predmetov različnih tipov (tudi vseh datotek) in
jih nadomestili z enim samim, ki bo definiran za \emph{posplošen tip}
-- \emph{večobličen} ali \emph{polimorfen} \emph{tip}.

\subsection*{\textit{Ad-hoc} polimorfizem}

Najprej bomo uporabili polimorfizem, ki se imenuje
\emph{\textit{ad-hoc} polimorfizem} ali drugače -- za silo narejen
polimorfizem.

Razlika med \texttt{int}, \texttt{float}, ...  polimorfizmi je v
velikosti obsega in tako prostora v pomnilniku, ki ga zaseda en
predmet posameznega razreda (tipa). Če vemo kje je element in kako
velik je, lahko naredimo izvedbeni modul neodvisno od \texttt{int},
\texttt{float}, ...

Izhajali bomo iz razreda skladov celih števil \texttt{SKLAD$\_$NO.h}
in opisali potrebne spremembe na njem. Najprej kreatorju dodamo
parameter, ki pove, koliko prostora zavzame en element (predmet)
naložen na sklad.

Zakaj imamo sedaj dva kreatorja? (ponovitev)
%
\begin{itemize}
\item S kreatorjem \texttt{Sklad()} še ne vemo koliko prostora lahko
  zasedemo za potrebe sklada.
\item S kreatorjem \texttt{Sklad(int min$\_$vel$\_$sklad)} določimo
  koliko prostora najmanj bo zasedel sklad.
\end{itemize}

Ta dva kreatorja sedaj razširimo na:
%
\begin{itemize}
\item \texttt{Sklad(velElt)} in
\item \texttt{Sklad(velElt, min$\_$vel$\_$sklad)}
\end{itemize}
%
kjer \texttt{velElt} opisuje koliko prostora zasede en predmet naložen
na sklad. To velikost dodamo med privatne stvari razreda skladov.

Poleg tega spremenimo še ostale funkcije:
%
\begin{itemize}
\item \texttt{Nalozi(naslov)}: ker je velikost za vse predmete, ki jih
  nalagamo na sklad enaka, potrebujemo za izvedbo nalaganja samo še
  podatek o mestu, kjer se nahaja nalagani predmet -- njegov
  \emph{naslov}.
\item \texttt{Zlozi(naslov$\_$zlaganja)}: podobno za zlaganje
  potrebujemo samo prostor, kam naj zložimo predmet -- potrebujemo
  \emph{referenco} predmeta v katerega bomo prepisovali.
\item \texttt{Vrh(naslov$\_$prepisovanja)}: isto velja za vrh.
\item Funkciji \texttt{Prazen} in \texttt{Poln} sta nespremenjeni.
\end{itemize}

V izvedbenem modulu sta spremenjene funkcije za nalaganje, zlaganje in
vračanje vrha. Za razliko od starega nalaganja, kjer je bil predmet
prenešen po vrednosti in smo ga lahko v enem kosu naložili na sklad,
moramo pri novem nalaganju to početi po koščkih. En košček je veliko
kot en znak (\texttt{char}), njihovo število pa je določeno ob
kreiranju -- \emph{velElt}:
{\tt
\begin{verbatim}
for(i= 0; i < velElt; i++)
  ptr_skladisce[zadnji][i]=element[i];
\end{verbatim}
}

Sedaj lahko uporabljamo naš \textit{ad-hoc} polimorfni razred skladov
predmetov na naslednji način:
%
{\tt
\begin{verbatim}
int main() {
  Sklad s1(sizeof(int));      // kliče: Sklad(velElt)
  Sklad s2(sizeof(int), 3);   // kliče: Sklad(velElt, min_vel_sklad)
  Sklad s3(sizeof(float));
  Sklad s4(sizeof(Crac));
  int i;
  float f;
  Crac r;

  s1.Nalozi(&i);
  s2.Nalozi(&i);
  s3.Nalozi(&f);
  s4.Nalozi(&r);

  return 0;
}; // main
\end{verbatim}
}
%
Žal po nesreči lahko napišemo tudi:
{\tt
\begin{verbatim}
  s4.Nalozi(&i);
\end{verbatim}
}
%
in naš program bo deloval napačno. Formalno gledano smo kršili
pogodbo, saj predpogoj zahteva, da je sklad \texttt{s4} sklad
racionalnih števil in ne celih.

\subsection*{Polimorfizem z vzorci / kalupi -- \textit{templates}}

Kako delujejo kalupi(vzorci)?
%
Ko naredimo funkcijo, razred ali kaj podobnega, lahko rečemo, da bo to
le vzorec (kalup), ki bo sicer kot tak neuporaben in bo postal
resnična funkcija (razred, ...) šele, ko bomo določili dodatne
parametre.

Sintaksa definicije vzorca je:
%
\[
  \texttt{template} < \textrm{template-argument-list} > \textrm{declaration}
\]
%
primer:
%
\[
  \texttt{template} <\texttt{type tSklElt}> \texttt{classSklad} ...
\]

Za naše potrebe, kjer bomo definirali vzorec razreda skladov predmetov
iz nekega drugega razreda, boma namesto \texttt{type} zapisali
\texttt{class} -- parameter našega vzorca je pač \emph{razred}
predmetov, ki so naloženi na sklad:
%
{\tt
\begin{verbatim}
  template <class tSklElt> Sklad { ... };
\end{verbatim}
}
%
Rezervirana besedica \emph{template} (kalup, vzorec) nakazuje, da
definiramo kalupni razred \texttt{Sklad}. Ta kalup ima kot parameter
razred \texttt{tSklElt} -- to je razred predmetov naloženih na sklad.
Njegova deklaracija  seže \textbf{samo do konca deklaracijskega kalupa
  razreda}. Ko je konec deklaracije razreda, prevajalnik razreda
\texttt{tSklElt} ne pozna več!

Seveda takšen kalup razreda ni takoj uporaben, saj ne ve, kaj
\texttt{tSklElt} sploh predstavlja. Zato moramo pred uporabo povedati
s kakšen razred (tip) predstavlja \texttt{tSklElt}:
%
{\tt
\begin{verbatim}
  Sklad <int>.
\end{verbatim}
}
%
S tem iz kalupa naredimo razred skladov celih števil. Kako izgleda
celoten program si lahko ogledate na:
\[
  \texttt{Z:}
     \backslash\texttt{PREDAVANJA}
     \backslash\texttt{POLDE}
     \backslash\texttt{code}
     \backslash\texttt{Sklad}
     \backslash\texttt{Skladi.h}
\]
%
To ni samo definicijski modul, ampak vključuje tudi izvedbeni modul.

Primer uporabe:
{\tt
\begin{verbatim}
int main() {
  Sklad<int>   s1;
  Sklad<int>   s2(3);
  Sklad<float> s3;
  .
  .
  .
};
\end{verbatim}
}

\section*{Ada}

V programski jeziku ada, se vzorci imenujejo \emph{generični tipi}.

Programski jezik ada nosi ime po \emph{Lady Ada Lovelace}, nečakinji
Lord Byrona. Ada je bila prva programerka v zgodovini in sicer je
programirala prvi ,,resnični`` računalnik. Le tega je okoli leta 1850
naredil \emph{Charles Babbage} ter ga imenoval \emph{analitični
  stroj}.

\end{document}
