Twitter und Facebook-Anbindung
X
Tweet Follow @twitterapi
!!! Anbindung an twitter und facebook öffnen !!!

Wenn Ihnen mein Online-Buch gefällt,
dann bedanken Sie sich doch mit einer kleinen Spende...

24.5.3 Typdefinitionen innerhalb von Templates

24.5.3 Typdefinitionen innerhalb von Templates

Gerade bei Templateklassen macht es Sinn, zu Beginn öffentliche Typdefinitionen zu deklarieren, um sich später den Aufruf bzw. die Deklaration von Variablen, zu vereinfachen und übersichtlicher zu gestalten. Folgendes Beispiel soll dies demonstrieren.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
					
// Sehr einfacher Datencontainer //////////////////////////////////////////////
template<typename TDataType = float, unsigned int TSize = 16>
class CContainer {
	public:
		typedef TDataType			TType;	// Für externen Gebrauch
		typedef CContainer<TDataType, TSize>	TSelf;	// Für internen Gebrauch



		// Standardkonstruktor ////////////////////////////////////////////////
		CContainer() {} ///////////////////////////////////////////////////////

		// Kopierkonstruktor //////////////////////////////////////////////////
		CContainer(TSelf& oContainer) {
			for (unsigned int iCount = 0; iCount < TSize; ++iCount) {
				m_aItems[iCount] = oContainer.m_aItems[iCount];
			} // end of for
		} // CContainer ///////////////////////////////////////////////////////

		// Setzt den Wert im Container an einer gewünschten Position //////////
		inline void SetValue(unsigned int iIndex, TDataType tValue) {
			// Wenn der Index gültig ist
			if (iIndex < TSize)	m_aItems[iIndex] = tValue;
			else			throw "Invalid Index";
		} // GetValue /////////////////////////////////////////////////////////

		// Holt den Wert an einer gewünschten Position aus dem Container //////
		inline TDataType GetValue(unsigned int iIndex) {
			// Wenn der Index gültig ist
			if (iIndex < TSize)	return m_aItems[iIndex];
			else			throw "Invalid Index";
		} // GetValue /////////////////////////////////////////////////////////

		// Gibt die Größe des Containers zurück ///////////////////////////////
		inline unsigned int GetSize() { return TSize; } ///////////////////////

	private:
		TDataType m_aItems[TSize];
};

// ...

// Achtung, jede Templatedefinition mit unterschiedlichen Templateparametern
// bedeutet auch ein unterschiedlicher Datentyp (nicht polymorph)! 
typedef CContainer<>		CSmallFloatContainer;	// float, 16
typedef CContainer<int>		CSmallIntContainer;	// int, 16
typedef CContainer<float, 128>	CBigFloatContainer;	// float, 128

// ...

CSmallFloatContainer		oContainer1;
CSmallFloatContainer::TType	fWert = 12.3f;
oContainer1.SetValue(0, fWert);

CSmallFloatContainer 		oContainer2(oContainer1);
fWert = oContainer2.GetValue(0);

printf("%i %g\n", oContainer2.GetSize(), fWert);
					

Ausgabe:

16 12.3
		

Zunächst ist zu sagen, dass ich mich der Übersichtlichkeit halber für die Inlineschreibweise entschieden habe. Zudem spart es Platz und richtet den Blick mehr aufs wesentliche. Das obige Beispiel implementiert eine Templateklasse, welches ein statisches Array kapselt. Zudem habe ich gleich in Zeile 2 festgelegt, dass es standardmäßig 16 Floats aufnehmen kann.

In den Zeilen 5 und 6 sehen Sie nun besagt öffentliche Typdefinitionen. Die erste ist sehr praktisch für den Zugriff von außen, wohingegen die zweite nützlich für den internen Zugriff ist, wie Sie in Zeile 14 sehen. Dort habe ich einen Kopierkonstruktor definiert. Ihm muss man ja immer eine Referenz auf ein Objekt gleichen Typs übergeben. Im Falle einer Templateklasse bedeutet dies, dass nicht nur der Klassenname ausreicht, sondern dass man auch hier wieder die spitzen Klammern und die Templateparameterdefinition benötigt. Durch die vorhergehende Typdefinition, also dem Alias, schafft man einen wesentlich schöneren Ausdruck und man läuft nicht Gefahr, dass man einen Parameter vergisst.

Der Rest der Klasse ist nicht weiter spannend. Ich habe lediglich einen Setter und zwei Getter eingebaut, welche das Holen bzw. Ändern der Werte ermöglichen.

Spannender sind dann wieder die Zeilen 45 bis 47. Erneut habe ich ein paar Typdefinitionen vorgenommen, um die Deklaration der Container zu vereinfachen. Besonders wichtig an dieser Stelle ist, dass jede Deklaration einen anderen Typ zur Folge hat. Es ist also nicht möglich, einen Container zu erzeugen, welcher Integer - und Floatcontainer aufnimmt. Es sind einfach unterschiedliche Typen/Klassen und ein Array kann immer nur einen Typ bzw. eine Klasse aufnehmen. Selbst ein Container mit 16 Floats und ein anderer mit 17 Floats, stellen unterschiedliche Typen/Klassen dar!

In Zeile 52 sehen Sie jetzt, wofür die erste öffentliche Typdefinition innerhalb der Templateklasse gut ist. In diesem Beispiel ist es zwar offensichtlich, dass man sich hier eine Variable vom Typ Float anlegen muss, aber die gezeigte Methode ist sicherer. Würde man beispielsweise einen anderen Container mit Integern erzeugen (also einfach den Templateparameter ändern), bräuchte man nicht noch diese Variable zu ändern (und ggf. auch nicht alle anderen im Programm). Man ist also wesentlich flexibler und typsicherer.

Der Rest ist dann nicht weiter spannend. Ich erzeuge einfach einen Container, packe eine Zahl rein, erzeuge mir eine Kopie des ersten Kontainers und hole dort den kopierten Wert wieder raus. Anschließend wird er ausgegeben.

Ich hoffe, ich konnte Ihnen ein weiteres mal die Deklaration von eigenen Typdefinitionen schmackhaft machen und den Umgang mit Templates erleichtern.

Zum Seitenanfang
Zum Inhaltsverzeichnis

© Copyright by Thomas Weiß, 2009 - 2012