Printing C:\Users\sreichel\Downloads\main-stl

Transcription

Printing C:\Users\sreichel\Downloads\main-stl
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
//
//
Beispielprogramm für die Benutzung einer STL-Liste
(c) Dipl.-Ing. S. Reichelt, BTU Cottbus-Senftenberg
#include <iostream>
// http://www.cplusplus.com/reference/iostream/
#include <list>
// Eine "list<T>" ist eine Art Sequenz-Container oder auch Container-Sequenz.
// Die einzelnen Elemente vom Typ "T" werden linear nacheinander angeordnet,
// intern als zweifach verkettete Liste.
// Dadurch können Elemente an beliebiger Stelle effektiv eingefügt, herausgelöst
// und verschoben werden. Iterationen sind vom Beginn zum Ende, von und zu
// beliebigen Stellen und auch in umgekehrter Richtung möglich.
// Dabei können sogar Algorithmen ausgeführt werden.
// (z.B. sortieren, suchen, ..., aber auch selbst definierte Algorithmen)
// http://www.cplusplus.com/reference/stl/list/
#include <algorithm>
// Eine Sammlung von Funktionen, die auf Sequenzen angewendet werden können.
// http://www.cplusplus.com/reference/algorithm/
using namespace std;
// Eine Test-Klasse als Beispiel für diese Demonstration.
// Sie wird sonst in zwei zusätzlichen Dateien definiert !!!
class Test{
int n;
public:
Test(int i) : n(i)
{ cout << "ctor(" << n << "):" << this << endl; };
~Test()
{ cout << "dtor(" << n << "):" << this << endl; };
void show() const
{ cout << "ich bin " << n << " :" << this << endl; };
// Die <algorithm>-Funktion for_each() erwartet als Parameter eine
// C-Funktion, die genau den Typ als Parameter besitzen muss, der
// in dem Listen-Container gespeichert ist.
// Der aktueller Parameter ist das Listenelement.
static // Ist keiner Instanz, nur der Klasse zugeordnet.
void showElement( Test const *pt )
{ pt->show(); };
};
// Eine STL-Liste, die als Elemente Pointer der Klasse Test enthält.
typedef list<Test*> Tlist;
// Damit man list<Test*> für den Iterator nicht noch einmal schreiben muss.
int main()
{
// Instanz einer verketteten Liste, die
// in den Containern Test-Pointer enthält
Tlist tList;
cout << "erstelle Elemente\n\n";
// drei neue Test-Instanzen erzeugen und am Ende der Liste anfügen
tList.push_back( new Test(1) );
tList.push_back( new Test(2) );
tList.push_back( new Test(3) );
cout << "fertig -> beginne Auflisten\n\n";
// So etwa sieht die Liste jetzt aus:
//
//
front
back
// Liste:
[Test*]--[Test*]--[Test*]--[]
//
^
^
//
|
|
// Iterator: begin
end
// Die klassische Variante, vor C++0x:
// Der Iterator ist eine Referenz auf einen Container,
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// begin() zeigt auf das erste Element.
// Es reicht ein const_iterator - wir verändern nichts.
for( Tlist::const_iterator it = tList.begin();
// solange das Ende noch nicht erreicht ist ...
it != tList.end();
// der operator++() ist überladen, er rückt zum nächsten Element weiter
it++ )
{
// *it repräsentiert den Inhalt des Containers,
// im Container befindet sich ein Pointer, also
// noch einmal dereferenzieren
(*it)->show();
// oder auch so:
// (*(*it)).show();
}
cout << " ... und noch einmal\n\n";
// ... für alle Elemente vom Anfang bis zum Ende
// führe je einmal die Methode "showElement" aus
// http://www.cplusplus.com/reference/algorithm/for_each/
for_each( tList.begin(), tList.end(), Test::showElement );
// Seit C++0x geht es viel einfacher:
//( Settings->Compiler: mindestens C++0x aktivieren [-std=c++0x] )
cout << "----------" << endl;
// Datentyp auto: Festlegung des Typs aus dem Kontext heraus
// ... und alle Elemente der Liste nacheinander
for(auto i: tList)
i->show();
cout << "\nfertig -> beginne Loeschen\n\n";
// Die erzeugten Elemente befinden sich noch in der Liste,
// sie müssen wieder zerstört werden.
for(auto i: tList)
// jedes Element zerstören
delete i;
// ... und die Pointer aus der Liste entfernen
tList.clear();
// Vorsicht: tList.clear() und tList.erase( tList.begin(), tList.end() );
// entfernen nur die Elemente, löschen/zerstören die Instanzen aber nicht !
// Da die Elemente nur Pointer sind, wird der Destruktor nicht aufgerufen !
/*
// Das wäre die klassische Variante ;)
// ... solange, bis die Liste leer ist
while( !tList.empty() )
{
//Das Element, das am Anfang steht merken ...
Test *p = tList.front();
// ... das erste Element von der Liste entfernen
tList.pop_front();
// ... und das Element selbst löschen / die Instanz zerstören.
delete p;
}
*/
cout << "fertig\n";
return 0;
}