Objektorientierte Programmierung und Templates

Werbung
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.1
Informatik I
Einführung
Algorithmus, Programmiersprache, Compiler und Linker
Datentypen
Kontrollstrukturen
Präprozessoranweisungen
Libraries
Funktionen und Klassen Objektorientierte Programmierung
Inhalte
08.05.2011
Dr.-Ing. habil. Jörg Wollnack
INFOB.2
Große Programmprojekte mit kommerziellen Libraries haben viele
Abhängigkeiten. Veränderungen der Programme können unübersichtliche
Seiteneffekte bewirken, die eine Weiterentwicklung unter wirtschaftlichen
Gesichtspunkten nicht mehr möglich macht.
Die Initialisierung und Weitergabe von großen Datenobjekten wird schnell
unübersichtlich. Eine Verwendung von globalen Datenobjekten kann hierbei
helfen, macht diese jedoch für sämtliche Module sichtbar. Dies ist häufig
nicht erwünscht und bietet Gefahren bei nicht vom Entwickler geplanten
Datenänderungen durch den Programmentwickler (Zugriff kann nicht gesperrt werden).
Die Kapselung der Daten über globale static Objekte der Module ist zwar
möglich, jedoch nicht konsequent genug.
Probleme komplexer Programmsysteme
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.3
Der Programmentwickler soll nur die für die Anwendung relevante Objekte
sehen und nutzen können. Dies erhöht die Code-Sicherheit und Wirtschaftlichkeit der Programmerstellung (protected-Objekte).
Der Zugriff auf Datenobjekte soll nur über definierte Interface in zulässiger
Weise erfolgen (Memberfunktionen).
Zwischen Datenobjekten und deren Operatoren existieren Verwandtschafts-, Teil- und Obermengenrelationen, die beim Programmentwurf
berücksichtigt werden sollen. Dies führt zur Wiederverwendbarkeit und
einfacheren Wartung von komplexen Programmsystemen.
Objektorientierte Programmierung I
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.4
Die strukturelle Verwandtschaft, die zumeist auch in der menschlichen
Schreibweise zum Ausdruck gebracht wird, soll sich möglichst in der
Programmnotation wiederfinden. Dies führt zur besseren Lesbarkeit durch
den Menschen und damit zu sichereren und wirtschaftlicheren Programmsystemen.
Die vom Menschen entwickelten Algebren sollen in einer möglichst
ähnlichen Notation im Programmcode ausgedrückt werden können. C++
kommt diesem Ziel durch überladbare Memberfunktionen und Operatoren
recht nahe. Die Rangfolgen der Operatoren können jedoch nicht geändert
werden.
Objektorientierte Programmierung II
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.5
+
-
*
/
%
^
!
=
<
>
+=
–=
^=
&=
|=
<<
>>
<<=
<=
>=
&&
||
++
––
()
[]
new
delete
&
|
~
*=
/=
%=
>>=
==
!=
,
–>
–>*
In C++ überladbare Operatoren. Rangordnung bleibt
unverändert.
Scientific Pascal war bereits vor ca. 20 Jahren weiter. Die Rangordnung von Operatoren
konnte vom Entwickler festgelegt werden. Dies erfordert jedoch eine fundierte
mathematische Ausbildung.
Objektorientierte Programmierung III
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.6
Einstelliger/unärer Operator (op)
y = op x
Zweistelliger/binärer Operator
y = u op v
Warum nicht auch so
programmieren?
op:= Operator auf dem Objekt
Algebra reeller und komplexer Zahlen
y = (a + c) + u ⋅ (b + d / e + g)v
Vektoralgebra
y = (a + c) + u ⋅ (b + d × e + g)
Matrixalgebra
Y = M−1 ⋅ (A + C)t + Un ⋅ (b + d)
Objektorientierte Programmierung IV
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.7
Der Programmentwurf soll auf einer höheren Abstraktionsebene möglich
sein. Die hierfür erforderliche Übersetzungsarbeit soll nach Implementation
der Objekte der Compiler und nicht der Mensch vollziehen. Dies erhöht
Sicherheit und Wirtschaftlichkeit von komplexen Programmsystemen.
Die Implementation z.B. einer Vektor- und Matrixalgebra kann für double,
long double, complex und long complex Datentypen erfolgen. Die Anpassungen an diese Varianten soll vom Compiler und nicht von Menschen
erfolgen. Dies erhöht Sicherheit und Wirtschaftlichkeit von komplexen
Programmsystemen. In C++ lassen sich hierfür Templates heranziehen
(Template := engl. Vorlage).
Objektorientierte Programmierung V
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.8
Die objektorientierte Programmierung führt vermehrt
dazu, dass Informatiker erst denken und dann
programmieren sollten
(Im Grunde gilt dies natürlich für alle Menschen).
Objektorientierte Programmierung VI
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.9
Vektor- und Matrixanordnungen sind für beliebige Datenobjekte zweckmäßig
(Rot,Grün,Blau)-Vektor eines Bildpunktes eines
y
2-dimensionalen Bildes, Tabelle von Namen,
Anordnung von Zahlen, Jacobi-Matrix von
Vektorfunktionen über Templates umsetzen).
Hierauf fußend könnte man für double, long double, complex und long
complex Zahlen eine Matrixalgebra aufbauen (Ableitung).
x
Diese Beispiele zeigen den Bedarf sowohl für das Ableiten von Klassen aus
Basisklassen (Vektor- und Matrixanordnung
Vektor- und Matrixalgebra) als
auch Templates (Einsetzen verschiedener Datentypen in Programmvorlagen).
Beispiele für Ableitungen und Templates
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.10
y
V( x, y) ≡
 R
 
V =  G  , R, G, B ∈{0,...,255}
 B
 
( x, y) ∈{0,..., xMax }×{0,..., yMax }
x
Vektorabbildungen in der Bildverarbeitung
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.11
class [tag [: base-list ]]
{
member-list
} [declarators];
// Definition/Deklaration (Header)
[class] tag declarators;
// Instanz (Applikation)
Typ tag::member(arg-list) // Implementation (Modul)
{
statement;
}
Syntax einer Klasse
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.12
Klassen sind verwandt mit
Strukturen, lassen jedoch eine
konsequente Strukturierung der
Objekte zu.
Klassen und Strukturen
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.13
class CName : BasisKlasse
{
protected:
Typ
m_TVarname;
…
private:
Typ
…
FunktionName(argliste);
// abgeleitetes Klassenobjekt
// public CObject für Windows verwenden
// gekapselte Datenobjekte
// Nur für Memberfunktionen
public:
CName();
CName(argliste);
CName(const CName& Varname)
~CName()
// öffentliches Interface
// void Konstruktor (default)
// Konstruktor (Initialisierung)
// Copy-Konstruktor (Initialisierung)
// Destruktor
Typ
…
};
// Memberfunktion
FunktionName(argliste);
Definition einer Klasse (Header)
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.14
CName::CName()
{
statement;
}
// void Konstruktor
// Wird benötigt, wenn Objekt Element eines
// C-Vektors sein kann.
CName::CName(argliste)
{
statement;
}
// Konstruktor
// Z.B. dynamische Datenobjekte anlegen
// Initialisierung usw.
~CName::CName()
{
statement;
}
// Destruktor
// Z.B. dynamische Datenobjekte frei geben
Typ CName::FunktionName(argliste)
{
statement;
}
// Memberfunktion
Implementation einer Klasse (Modul)
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.15
int main()
{
CName InstanzName(Arg);
Typ
TReturnValue;
// Objekt anlegen
CName * pInstanzName = new CName[4];
// Vektor mit void-Objekten anlegen
TReturnValue = InstanzName.FunktionName(Arg);
// Memberfunktion von Objekt
pInstanzeName[2].CName(Arg);
// Element des Vektors anlegen
TReturnValue = pInstanzeName[2].FunktionName(Arg); // Memberfunktion von Objekt
delete [] pInstanzName;
};
// Speicher frei geben
Instanz einer Klasse (Applikation)
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.16
Konstruktoren, Destruktoren, Memberfunktionen und Operatoren
repräsentieren Methoden der Klasse/des Objekts.
Sie können explizit oder implizit als inline definiert werden.
Im ersten Fall wird das Schlüsselwort inline der Definition vorangestellt. Die
Implementation der inline-Funktion sollte in der selben Header-Datei
erfolgen, da der Compiler diese kennen muss.
Kurze inline Methoden können direkt innerhalb der Klasse implizit
implementiert werden. Das Schlüsselwort ist hierbei nicht zwingend
erforderlich.
Methoden
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.17
Konstruktoren: Vollziehen eine Initialisierung des Objekts und haben den
Namen der Klasse. Konstruktoren müssen sich durch ihre Signatur unterscheiden (Anzahl, Typ und Reihenfolge der Parameter) (CClassName(Argliste)).
Default-Konstruktor: Ist ein Konstruktor ohne Parameter und setzt die
Elemente des Objekts auf Standardwerte. Wird dieser nicht implementiert, so
erzeugt der Compiler eine Minimalversion ohne Initialisierung der Elemente.
Existiert mindestens ein Konstruktor, so muss der Default-Konstruktor explizit
definiert werden. Sollen die Objekte als Vektorelemente dienen (new
CClassName[…]), so ist ein Default-Konstruktor erforderlich
(CClassName(void)).
Copy-Konstruktor: Initialisiert ein Objekt mit einem anderen desselben Typs
und muss vom Entwickler implementiert werden. Dieser Konstruktor wird
aufgerufen, wenn ein Call by Value erfolgt (CClassName(CClassName& x)).
Konstruktoren und Destruktoren I
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.18
Destruktor: Der Destruktur vollzieht einen geregelten Abbau des durch einen
Konstruktor aufgebauten Objekts. Z.B. müssen Elemente, die Speicherplatz
über eine Konstruktor reservieren, wieder freigeben werden. Sein Name ist
identisch mit dem Namen der Klasse mit der Tilde ~ als Präfix und er hat keine
Argumente (~CClassName()).
Der Aufruf erfolgt automatisch, wenn die Lebensdauer eines Objekts beendet
ist. Bei einem lokalen Objekt am Ende eines Blockes und bei globalen oder
static Objekten am Ende des Programms. Der Aufruf erfolgt auch, wenn mit
delete ein mit new erzeugtes Objekt zerstört wird.
Konstruktoren und Destruktoren II
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.19
Zuweisungs-Operator: Kopiert ein Objekt in ein existierendes Objekt gleichen
Typs. Dieser Operator muss vom Entwickler implementiert werden.
Memberfunktionen: Haben Zugriff auf die Elemente des Objekts.
this-Pointer: Ein konstanter Zeiger auf das Objekts innerhalb einer
Memberfunktion.
Konstruktoren und Destruktoren II
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.20
Rückgabe als Kopie: Ist rechenzeitintensiv, da Daten auf über den Stack
übergeben werden. Insofern nur für kleine Objekte sinnvoll. Die Kopie vollzieht
der copy-Konstruktor.
Rückgabe als Referenz: Wird intern als Pointer zurückgegeben und ist
deshalb effizient. Die Lebensdauer des Objekts darf nicht lokal sein. Eine
Deklaration als static Objekt wäre denkbar, bietet jedoch die Gefahr von
Quereffekten.
Rückgabe als Pointer: Diese explizite Pointer Rückgabe ist analog zur
Referenz, weshalb auch hier die Lebensdauer des Objekts nicht lokal sein
darf.
Objekte als return-Werte
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.21
template < [TypenListe] [,[ArgListe]] > Deklaration
template <class T, int i> class TestClass // Deklaration
{
public:
char buffer[i];
T
testFunc(T* p1 );
};
(Header)
template<class T, int i>
T TestClass<T,i>::testFunc(T* p1)
{
return *(p1++);
};
// Implementation
(Modul)
TestClass<char, 5> ClassInst;
// Instanz
(Applikation)
Templates
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.22
template <class T> void Swap(T& a,T& b)
{
T c = a;
a = b;
b = c;
}
Funktions-Template
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.23
template <class T, int i> class TemplClass
{
public:
TemplClass(void);
~TemplClass(void);
int MemberSet(T a, int b);
private:
T TArray[i];
int ArraySize;
};
Klassen-Template
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.24
#define min(i, j) (((i) < (j)) ? (i) : (j))
template<class T> T min (T i, T j) { return ((i < j) ? i : j) }
There is no way for the compiler to verify that the macro parameters are of
compatible types. The macro is expanded without any special type checking.
The i and j parameters are evaluated twice. For example, if either parameter
has a postincremented variable, the increment is performed two times.
Because macros are expanded by the preprocessor, compiler error messages
will refer to the expanded macro, rather than the macro definition itself. Also,
the macro will show up in expanded form during debugging [Microsoft].
Makros versus Templates
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.25
CString::CString(char* cp);
Konvertierungskonstruktor (Member)
Klasse
Anderer Datentyp
Konvertierungsfunktion (Member)
operator Typ(void) const;
Konvertierung für Klassen/Objekte I
Dr.-Ing. habil. Jörg Wollnack
08.05.2011
INFOB.26
Ist der Zieltyp eine Klasse, so sollten Konvertierungskonstruktoren eingesetzt
werden. Soll das Objekt in der die Zielklasse unverändert sein, so sind
Konvertierungsfunktionen vorzuziehen.
Mehrdeutigkeiten bei den Konvertierungen können durch explizite
Konvertierungen ausgeschlossen werden.
Mögliche Mehrdeutigkeitsproblem lassen sich mindern, indem man Methoden
AsTyp(void) implementiert, mit denen man eine explizite Typenumwandlung
vollziehen kann.
Konvertierung für Klassen/Objekte II
Herunterladen