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; }