\documentclass[twoside]{article}
\usepackage{isolatin1}
\usepackage{german}
\usepackage{palatino}
\usepackage{fancyheadings}
\parindent0pt
\parskip1ex

\oddsidemargin0mm
\evensidemargin0mm
\textwidth160mm
\topmargin-16mm
\headsep8mm
\textheight255mm
\footskip10mm


\begin{document}
\thispagestyle{empty}

{\sffamily{\bfseries{\Huge

\centerline{Informatikpraktikum CE2}
\vspace{100mm}
\centerline{Übung 1: Einfach verkettete Liste}
}}}



\vspace{130mm}

\textsf{\small{\copyright\ Torben Nehmer{\tt<}Torben.Nehmer@gmx.net{\tt>} 1998 }}

\newpage
\pagestyle{fancyplain}
\tableofcontents

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Anforderungen an die Liste
\newpage
\section{Anforderungen an die Liste}
Da die Hauptaufgabe der Liste im speichern von wenigen Listenelementen
bestehen wird, ist der Aufbau der Liste relativ simpel gehalten. Es
werden keine Optimierungen für schnellen Listenzugriff
implementiert. Die Datenstrukturen und Funktionen sind auf eine
einfach verkettete Liste ausgelegt.

Die Listenklasse hat in diesem Fall den Namen \texttt{CList}. Die
einzelen Listenelemente werden ebenfalls in Klassenform gespeichert,
wobei die Klassendefinition hier in der Listenklasse selbst
eingeschlossen ist, um das Prinzip der Kaspelung zu halten. Der Name
der Listenelement - Hilfsklasse ist \texttt{CList:: CElement}.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Beschreibung der notwendigen Funktionen

\subsection{Beschreibung der notwendigen Funktionen}
Es werden fünf Gruppen von Funktionen vorgesehen:
\begin{itemize}
\item Konstruktion / Destruktion
\item Datenzugriffsfunktionen
\item Hilfsfunktionen zur Statusabfrage
\item private Hilfsfunktionen
\item Debug - Funktionen
\end{itemize}

% Construction / Destruction
\subsubsection{Konstruktion / Destruktion}

% Constructor
\textbf{\textsf{Konstruktor:}}\\
{\ttfamily 
template <class T>\\
CList<T>::CList();
}

Der Konstruktor initialisiert lediglich die Member-Variable auf das
erste Listenelement auf NULL, um den Korrekten interen Zustand der
Liste herzustellen.

% Destructor
\textbf{\textsf{Destruktor:}}\\
{\ttfamily
template <class T>\\
CList<T>::$\sim$Clist();
}

Der Destruktor der Liste zerstört sämtliche erzeugten Listenelment -
Objekte. Die \emph{direkt} darin gespeicherten Daten gehen dadurch
verloren. Werden Pointer in der Liste gespeichert, werden die darin
angegebenen Speicherbereiche \emph{nicht} freigegeben.

% Data Access Member Functions
\subsubsection{Datenzugriffsfunktionen}
Es werden drei Datenzugriffsfunktionen vorgesehen. Die beiden lesenden
Funktionen nutzen Referenzparameter um die gesicherten Daten
zurückzuliefern. 

% AddData
\textbf{\textsf{Element sichern}}\\
{\ttfamily
template <class T>\\
void CList<T>::AddData (T pData);
}

Diese Zugriffsfunktion fügt das Datum pData am Ende der Liste
ein. Weitere Fehlerkontrollen oder -werte sind hier nicht notwendig.

\emph{Parameter:}
\begin{itemize}
\item \emph{T pData:} Zu speicherndes Datum
\end{itemize}

% GetData
\textbf{\textsf{Element lesen}}\\
{\ttfamily
template <class T>\\
virtual int CList::<T>::GetData (int iPos, T \& pResult);
}

GetData liefert im übergebenen Referenzparameter ein gespeicherte
Datum zurück.

\newpage
\emph{Parameter:}
\begin{itemize}
\item \emph{int iPos:} Index für das gesuchte Element. Die Indizierung
beginnt bei 1.
\item \emph{T \& pResult:} Rückgabeparameter für das gesuchte Datum.
\end{itemize}

\emph{Rückgabewerte:}
\begin{itemize}
\item \emph{0:} Das zurückgelieferte Datum is ungültig, da der Index
nicht innerhalb des gültigen Bereiches lag.
\item \emph{1:} Funktionsaufruf erfolgreich.
\end{itemize}

% RemoveData
\textbf{\textsf{Element lesen und entfernen}}\\
{\ttfamily
template <class T>\\
virtual int CList<T>::RemoveData (int iPos, T \& pResult);
}

RemoveData liefert, wie GetData, ein gespeichertes Datum
zurück. Einziger Unterschied zu GetData liegt darin, das das
zurückgelieferte Listenelement gleichzeitig aus der Liste entfernt wird.

\emph{Parameter:}
\begin{itemize}
\item \emph{int iPos:} Index für das gesuchte Element. Die Indizierung
beginnt bei 1.
\item \emph{T \& pResult:} Rückgabeparameter für das gesuchte Datum.
\end{itemize}

\emph{Rückgabewerte:}
\begin{itemize}
\item \emph{0:} Das zurückgelieferte Datum is ungültig, da der Index
nicht innerhalb des gültigen Bereiches lag.
\item \emph{1:} Funktionsaufruf erfolgreich.
\end{itemize}

% Status Functions
\subsubsection{Hilfsfunktionen zur Statusabfrage}

% IsEmpty
\textbf{\textsf{Status: Liste leer}}\\
{\ttfamily
template <class T>\\
int CList<T>::IsEmpty();
}

Mit Hilfe von IsEmpty kann festgestellt werden, ob bereits Elemente in
der Liste gespeichert sind.

\emph{Rückgabewerte:}
\begin{itemize}
\item \emph{0:} Die Liste ist leer.
\item \emph{1:} Die Liste enthält mindestens ein Element.
\end{itemize}

% private Member Functions
\subsubsection{Private Hilfsfunktionen}

% GetElement
\textbf{\textsf{Suchen eines bestimmten Listenelementes}}\\
{\ttfamily
private:\\
template <class T>\\
virtual CList<T>::CElement * CList<T>::GetElement (int iPos);
}

Die private Hilfsfunktion GetElement sucht auf der Basis des Indexes
\emph{iPos} ein Element der Liste.

\emph{Parameter:}
\begin{itemize}
\item \emph{int iPos:} Index für das gesuchte Element. Die Indizierung
beginnt bei 1.
\end{itemize}

\emph{Rückgabewerte:}
\begin{itemize}
\item \emph{NULL:} Das gesuchte Element wurde nicht gefunden. Der
Index ist ausserhalb des gültigen Bereiches.
\item \emph{!(NULL):} Der zurückgelieferte Wert ist ein gültiger
\texttt{CElement} Zeiger, der auf das gesuchte Element zeigt.
\end{itemize}

% Hilfsklasse CElement
\textbf{\textsf{Hilfsklasse CList::CElement}}

Diese private Hilfsklasse wird zum speichern der einzelnen
Listenelemente verwendet. Die Funktionen in dieser Klasse beschränken
sich auf Zugriffsfunktionen auf die einzelnen Datenelemente und werden
im nächsten Abschnitt näher erläutert. Ich will hier an dieser Stelle
lediglich auf den Konstruktor dieser Hilfsklasse eingehen:

% Constructor of CElement
\textbf{\textsf{Konstruktor der Hilfsklasse CElement}}\\
{\ttfamily
template <class T>\\
CList<T>::CElement::CElement (CElement * pNext, T pData);
}

Dieser Konstruktor initialisiert die beiden Member-Variablen der
Hilfsklase \texttt{CElement}.

\emph{Parameter:}
\begin{itemize}
\item \emph{CElement * pNext:} Initialisiert den Zeiger auf das
nächste Datenelement.
\item \emph{T pData:} Initialisiert das Datum innerhalb des
Listenelements.
\end{itemize}

% Debug - Funktionen
\subsubsection{Debug - Funktionen}
Augeblicklich existiert lediglich eine einzige Debug - Funktion zur
Ausgabe des aktuellen Listeninhaltes. Diese Funktionen werden nur dann
genutzt werden, wenn während des kompilierens das Define
\texttt{\_DEBUG} gesetzt ist.

% Dump
\textbf{\textsf{Ausgeben des aktuellen Listeninhaltes}}\\
{\ttfamily
\#ifdef \_DEBUG\\
template <class T>\\
void CList<T>::Dump();\\
\#endif //\_DEBUG
}

Die Dump Funktion von jedem vorhandenen Listenelement die
Speicheradresse aus und übergibt das dereferenzierte Datum dem
IOStream cout. Aus diesem Grunde kann diese Funktion nur dann
angewendet werden, wenn die Liste für Pointer genutzt wird und für
diese Pointer der Stream - Operator \char92<<\char34 definiert ist.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Beschreibung der Datenstrukturen

\subsection{Beschreibung der notwendigen Datenstrukturen}
Für die Listenklasse benötigt zwei Datenstrukturen, die im folgenden
näher erläutert werden:
\begin{itemize}
\item Daten zur Verwaltung der Liste selbst
\item Datenstruktur zum speichern der Daten
\end{itemize}


% CList::m_pFirst
\subsubsection{Verwaltung der Liste}
\textbf{\textsf{Zeiger auf Listenanfang}}\\
{\ttfamily
template <class T>\\
class CList<T>\\
\{...\\
private:\\
CElement * m\_pFirst;\\
...\}
}

Dieser Zeiger verweist auf das erste Listenelement. Ist die Liste
leer, so hat dieser Zeiger den Wert NULL.

\emph{Zugriffsfunktionen:}
Für \texttt{m\_pFirst} sind keine Zugriffsfunktionen definiert, da eine
Änderung dieses Zeigers nur von der Liste korrekt durchgeführt werden
kann.

% CElement
\subsubsection{Hilfsklasse zum speichern der Daten}
Die Listenelemente besitzen zwei Member-Variablen, die benötigt werden
um die Anforderungen der Aufgabe zu erfüllen:

\newpage
% CElement::m_pNext
\textbf{\textsf{Zeiger auf nächstes Listenelement}}\\
{\ttfamily
template <class T>\\
class CList<T>::CElement\\
\{...\\
  private:\\
  CElement * m\_pNext;\\
...\}
}

Dieser Zeiger verweist auf das nächste Listenelement. Ist er NULL, so
ist as Ende der Liste erreicht.

\emph{Zugriffsfunktionen:}
\begin{itemize}
\item \texttt{CElement * GetNext():} Lesen der Variable
\item \texttt{void SetNext (CElement *):} Setzen der Variable
\end{itemize}

% CElement::m_pData
\textbf{\textsf{Specherbereich für Datum}}\\
{\ttfamily
template <class T>\\
class CList<T>::CElement\\
\{...\\
  private:\\
  T m\_pData;\\
...\}
}

In dieser Variable wird das zu sichernde Datum gespeichert.

\emph{Zugriffsfunktionen:}
\begin{itemize}
\item \texttt{T GetData():} Lesen der Variable
\item \texttt{void SetData(T data):} Setzen der Variable
\end{itemize}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Beschreibung der Funktions - Algorithmen

\subsection{Festlegung der Funktions - Algorithmen}

Die Listenklasse benötigt in der aktuellen Implementierung lediglich
einen Algorithmus zum Suchen der benötigten Daten. Dieser ist in der
Funktion \texttt{CList::GetElement(int iPos)} realisiert. Es wird das
einfachste mögliche System genutzt: Die Daten werden linear
durchsucht, bis das gesuchte Element gefunden wird oder das Ende der
Liste erreicht ist.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Anforderungen an die Liste
\newpage
\section{Beschreibung der Klassenstruktur}
Der genaue Aufbau der Klasse \texttt{CList} dürfte aus dem Listing
\texttt{CList.h} und der Funktionsbeschreibung aus Kapitel 1
ausreichend hervorgehen. Ich möchte trotzdem auf
einige wesentliche Dinge der Klassenstruktur eingehen.

\subsection{Schnittstellenfunktionen}

\subsubsection{Zugriffsfunktionen}
Alle lesenden Zugriffsfunktionen fordern die Angabe eines Indexes,
wodurch mehrere Objekte die gleiche Liste simultan nutzen
können. Zugriffsfunktionen im Stile von MoveNext oder MovePrevious
würden hier die Verwendbarkeit einschränken, da Zugriffsnummern
eingeführt werden müßten.

\subsubsection{Virtuelle, öffentliche Funktionen}
Um sicherzustellen, daß die Liste als Basisklasse für zukünftige
Erweiterungen verwendbar ist, wurden mehrere Member -
Funktionen als \texttt{virtual} deklariert:\\
{\ttfamily
template <class T>\\
class CList<T>\\
\{...\\
public:\\
virtual int RemoveData (int iPos, T \& pResult);\\
virtual int AddData (T pData);\\
...\}
}

Es ist nicht notwendig, die Zugriffsfunktion \texttt{CList<T>::GetData}
virtuell zu implementieren, da sie, wie auch
\texttt{CList<T>::AddData} und \texttt{CList<T>::RemoveData}, auf eine
interne Hilfsfunktion zurückgreift um das angeforderte Listenelement
zu deklarieren. Dadurch wird in \texttt{CList<T>::GetData} nur noch
das Listenelement angefordert und danach das gespeicherte Datum
zurückgeliefert.

\subsubsection{Sonstige Funktionen}
\textsf{\textbf{int IsEmpty()}}\\
Je nach Anwendungsgebiet erschien es mir sinnvoll, eine Möglichkeit
zur Abfrage des \texttt{m\_pFirst} - Zeigers hinzuzufügen. Dadurch
erhält die Anwendung die Möglichkeit, auf eine leere Liste zu prüfen,
beispielsweise um bei Ausgabe - Funktionen einer komplizierte
Behandlung der ersten Ausgabe aus dem Weg zu gehen.

\textsf{\textbf{void Dump()}}\\
Zusätzlich existiert zur Fehlersuche eine Debugfunktion, die den
aktuellen Listeninhalt auf \texttt{cout} ausgiebt. Bedingung hierfür
ist, das die Liste mit \texttt{\_DEBUG} kompiliert wird. Es entsteht
folgende Bilschirmausgabe:
\begin{verbatim}
*** DEBUG - Ausgabe Objekt CList in 0x804a4a8
  Element 1 at 0x804a4c8 contains 1
  Element 2 at 0x804a4e8 contains 4
  Element 3 at 0x804a508 contains 9
  Element 4 at 0x804a528 contains 16
  Element 5 at 0x804a548 contains 25
*** DEBUG Ausgabe abgeschlossen
\end{verbatim}
Wie aus hierraus hervorgeht, werden ebenfalls die einzelnen
gesicherten Daten ausgegeben. Dies ist allerdings nur möglich, wenn
Zeiger gespeichert werden, und für die durch die Zeiger definierten
Objekte der Stream - Ausgabeoperator \texttt{<<} definiert ist.

Wird eine dieser Bedingungen nicht erfüllt, sollte auf die Verwendung
dieser Funktion verzichtet werden.

\subsection{Private Hilfsfunktionen}
Derzeit existiert eine einzige private Hilfsfunktion:\\
{\ttfamily
template <class T>\\
class CList<T>\\
\{...\\
private:
virtual CElement * GetElement (int iPos);\\
...\}
}

Diese Funktion ist das Kernstück der lesenden Zugriffsfunktionen. Sie
sucht jeweils das zu einem Index \texttt{iPos} passende CElement
Objekt und liefert es an die aufrufende Funktion zurück. Sollte die
Klasse erweitert werden ist hier ein einfacher Ansatzpunkt für alle
Zugriffsfunktionen, die einen Index dereferenzieren müssen.

\subsection{Private Hilfsklassen}
Die Klasse \texttt{CList} enthält eine Hilfsklasse, die als private
deklariert wurde, um eine weitere Klasse zum speichern der Daten zur
Verfügung zu stellen. Diese Klasse wurde einerseits intern implementiert,
um die Möglichkeit eines Namenskonflikte im globalen Namensraum zu
verhindern, und andererseits ist der Aufbau der Listenelemente nur für
die Listenklasse selbst von Bedeutung.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Anmerkungen
\newpage
\section{Anmerkungen des Autors}
Im Anhang befindet sich der komplette Quellcode der
Listenklasse. Vorschläge oder Verbesserungs\-wünsche nehme ich gerne
entgegen.

Anhang C stellt eine Beispielanwendung dar, die mit der Liste
arbeitet. Sie muß mit dem Define \_DE\-BUG kompiliert werden, da die
Debug-Funktionen genutzt werden.

Die komplette Listenklasse ist ebenfalls im Internet unter
\texttt{http://www.foo.fh-furtwangen.de/ $\sim$nehmer/clist.html}
erhältlich.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% ANHANG
\begin{appendix}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% CList.h
\newpage
\section{CList.h}
\begin{verbatim}
//////////////////////////////////////////////////////////////////////
//
//  LISTENKLASSE "CList" 
//
//  Datei:      CList.h
//  Zweck:      Einfach vorwaerts verkettete Liste zum speichern von
//              Pointern auf durch ein Template festgelegte Objekte.
//  Autor:      Torben Nehmer <Torben.Nehmer@gmx.net>
//  Version:    1.30 
//  Datum:      15.10.1998
//
//  Implementierung in:
//              CList.cpp
//
//////////////////////////////////////////////////////////////////////

#if !defined(INCLUDE_CLIST_HEADER)
#define INCLUDE_CLIST_HEADER

template <class T>
class CList
{
private:
//////////////////////////////////////////////////////////////////////
//  Hilfsklasse fuer Datenelemente
//
    class CElement
    {
    private:
      T m_pData;
       // Pointer auf Daten
      CElement * m_pNext;
       // Pointer auf naechstes Element
    public:
      CElement ( CElement * pNext, T pData);
       // Standardkonstruktor

    //////////////////////////////////////////////////////////////////
    //  Datenzugriffsfunktionen

      CElement * GetNext () const;
       // Liefert Pointer auf naechstes Element
      void SetNext ( CElement * pNext );
       // Setzt Pointer auf naechstes Element
      T GetData() const;
       // Liefert gespeicherte Daten
      void SetData (T data);
       // Setzt Daten
    };

       // Hilfsklasse zum speichern der Objektpointer. Definition als
       // Klasse, da Implementierung durch Konstruktor vereinfacht wird.

//////////////////////////////////////////////////////////////////////
//  Private Hilfsfunktionen
//
    virtual CElement * GetElement (int iPos) const;
       // Liefert Pointer auf n-tes Element oder NULL Pointer wenn
       // Element nicht vorhanden.

//////////////////////////////////////////////////////////////////////
//  Datenelemente
//
    CElement * m_pFirst;
        // Zeiger auf erstes Datenelement, wird vom Konstruktor
        // auf NULL initialisiert.
 
    
public:

//////////////////////////////////////////////////////////////////////
//  Kunstruktion / Destuktion
//
    CList();
        // Standardkonstruktor
    virtual ~CList();
        // Destruktor

//////////////////////////////////////////////////////////////////////
//  Zugriffsoperatoren
//
    int GetData (int iPos, T & pResult) const;
        // Liefert n-ten Datenpointer
    virtual int RemoveData (int iPos, T & pResult);
       	// Liefert n-ten Datenpointer und loescht Element

       	// GetData UND RemoveData geben 0 zurueck, wenn
       	// das gesuchte Element nicht existiert.

    virtual void AddData (T pData);
       	// Fuegt ein neues Element am Ende der Liste ein.


//////////////////////////////////////////////////////////////////////
//	Statusabfragen
//
    int IsEmpty () const; 
       	// TRUE, wenn Liste leer.

//////////////////////////////////////////////////////////////////////
//  Debug Funktionen
//  Gehen von 'T *' und definierten 'cout << ...' aus!
//
#ifdef _DEBUG
    void Dump () const;
        // Gibt Pointeradressen und Zeigerinhalte (als T *) auf
        // cout aus.

#endif // _DEBUG


};

//////////////////////////////////////////////////////////////////////
//  Include der Implementierung, sonst möglicher Fehler wg. Template
#include "CList.cpp"

#endif // INCLUDE_CLIST_HEADER
\end{verbatim}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% CList.cpp
\newpage
\section{CList.cpp}
\begin{verbatim}
//////////////////////////////////////////////////////////////////////
//
//  LISTENKLASSE "CList" - Implementierung
//
//  Datei:      CList.cpp
//  Autor:      Torben Nehmer <Torben.Nehmer@gmx.net>
//  
//////////////////////////////////////////////////////////////////////

#include <stdio.h>

//////////////////////////////////////////////////////////////////////
// Konstruktion / Destruktion
//

template <class T>
CList<T>::CList()
{
  // Standardkonstruktor initialisiert m_pFirst auf leere Liste
    m_pFirst = NULL;
}

template <class T>
CList<T>::~CList()
{
  // Destruktor entfernd noch vorhandende Speicherobjekte. Es werden
  // jedoch NICHT die gespeicherten Objekte geloescht.
    if (!IsEmpty())
    {
        CElement * pTemp = m_pFirst;
        CElement * pDel;
        while (pTemp)
        {
            pDel = pTemp;
            pTemp = pTemp->GetNext();
            delete pDel;
        }
    }
}

//////////////////////////////////////////////////////////////////////
//  Zugriffs - Funktionen
//

template <class T>
void CList<T>::AddData(T pData)
{
  // Fuegt einen neuen Listeneintrag am Ende der Liste ein.
    if (IsEmpty())
        m_pFirst = new CElement(NULL, pData);
    else
    {
        CElement * pLast = m_pFirst;
        while (pLast->GetNext())
            pLast = pLast->GetNext();
        pLast->SetNext(new CElement(NULL, pData));
    }
}

template <class T>
int CList<T>::GetData (int iPos, T & pResult) const
{
  // Liefert den Datensatz an der Stelle iPos zurueck, wobei die
  // Indizierung mit 1 beginnt.
  // Der gespeicherte Zeiger wird in pResult zurueckgeliefert.
  // Die Funktion selbst liefert TRUE (nonzero), falls der Aufruf
  // erfolgreich war.
    CElement * pElement = GetElement (iPos);
    if (pElement)
      {
	pResult = pElement->GetData();
	return 1;
      }
    else
      return 0;
}

template <class T>
int CList<T>::RemoveData (int iPos, T & pResult)
{
  // Liefert den Datensatz an der Stelle iPos zurueck, wobei die
  // Indizierung mit 1 beginnt. Der betroffene Eintrag wird aus
  // der Liste entfernt.
  // Der gespeicherte Zeiger wird in pResult zurueckgeliefert.
  // Die Funktion selbst liefert TRUE (nonzero), falls der Aufruf
  // erfolgreich war.
    CElement * pDel = GetElement (iPos);
    if (!pDel)
        return 0;

    if (iPos == 1)
        m_pFirst = pDel->GetNext();
    else
    {
        CElement * pPrev = GetElement (iPos - 1);
        pPrev->SetNext(pDel->GetNext());
    }
    pResult = pDel->GetData();
    delete pDel;
    return 1;
}

//////////////////////////////////////////////////////////////////////
//  Statusabfrage - Funktionen
//

template <class T>
inline int CList<T>::IsEmpty () const
{
  // Liefert TRUE (nonzero), wenn KEINE Elemente in der Liste 
  // vorhanden sind.
    return (!m_pFirst) ? 1 : 0;
}

//////////////////////////////////////////////////////////////////////
//  Private Hilfsfunktionen
//
template <class T>
CList<T>::CElement * CList<T>::GetElement(int iPos) const
{
  // Private Hilfsfunktion, die versucht, den Listeneintrag an der 
  // Stelle iPos zurueckzuliefern. Existiert ein solches Element,
  // wird der CElement Pointer darauf zurueckgegeben, ansonsten der
  // NULL Pointer.
    if (!m_pFirst || iPos < 1)
        return NULL;

    CElement * pTemp = m_pFirst;
    
    for (int i = 1; i < iPos; i++)
    {
        if (!pTemp->GetNext())
            return NULL;
        pTemp = pTemp->GetNext();
    }

    return pTemp;    
}

//////////////////////////////////////////////////////////////////////
//  Debug Funktionen
//


#ifdef _DEBUG

#include <iostream.h>

template <class T>
void CList<T>::Dump() const
{
  // DEBUG Funktion, mit deren Hilfe sich der Inhalt des Objektes 
  // MIT Speicheradressen nach COUT ausgegeben werden kann. Die 
  // gespeicherten Objekte muessen deshalb ueber einen definierten
  // Stream Output Operator verfuegen.
    CElement * pTemp;
    cout << "*** DEBUG - Ausgabe Objekt CList in " << this << endl;

    if (!IsEmpty())
    {
        pTemp = m_pFirst;
        int i = 1;
        while (pTemp)
        {
            cout << "  Element " << i++ << " at " << pTemp << " contains " 
                << *((T) pTemp->GetData()) << endl;
            pTemp = pTemp->GetNext();
        }
        cout << "*** DEBUG Ausgabe abgeschlossen\n";
    }
    else
        cout << "Keine Elemente vorhanden!\n*** DEBUG "
            << "Ausgabe abgeschlossen!\n";
}

#endif _DEBUG

//////////////////////////////////////////////////////////////////////
//  Implementierung Hilfsklasse CList::CElement
//  und deren Zugriffsfunktionen
//

template <class T>
CList<T>::CElement::CElement ( CElement * pNext, T pData)
  : m_pNext(pNext), m_pData(pData)
{
}

template <class T>
CList<T>::CElement * CList<T>::CElement::GetNext () const
{
  return m_pNext;
}

template <class T>
void CList<T>::CElement::SetNext ( CElement * pNext )
{
  m_pNext = pNext;
}

template <class T>
T CList<T>::CElement::GetData() const
{
  return m_pData;
}

template <class T>
void CList<T>::CElement::SetData (T data)
{
  m_pData = data;
}
\end{verbatim}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Beispiel: main.cpp
\newpage
\section{Beispiel: main.cpp}
\begin{verbatim}
//////////////////////////////////////////////////////////////////////
//
//  LISTENKLASSE "CList" - Beispielanwendung
//
//  Datei:      main.cpp
//  Autor:      Torben Nehmer <Torben.Nehmer@gmx.net>
//  
//////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <iostream.h>
#include "CList.h"

int main()
{
  // Liste erstellen
    CList<int *> * pList = new CList<int *>();         

    cout << "\nCreating list...\n\n";

    int * pInt;
    int iCount;
    
  // Liste füllen
    for (iCount = 1; iCount <= 5; iCount++)
    {
        pInt = new int;
        *pInt = iCount * iCount;
        pList->AddData (pInt);
    }

    cout << "\nList filled...\n\n";

    pList->Dump();

    cout << "\nRemoving from list...\n\n";
    
  // Liste leeren
    iCount=1;
    while (pList->RemoveData(1,pInt))
    {
       cout << "Executing loop " << iCount++ << " - Result of GetData: " << 
         *(pInt) << endl;
       delete pInt;
    }

    cout << "\nNew list contents...\nPress almost any key to continue\n\n";

    pList->Dump();
    

    
    return 0;
}
\end{verbatim}

\end{appendix}
\end{document}





