C++ für Fortgeschrittene |
#include <conio.h> int main() { std::cout << "hello, world (Brian Kernighan 1974)" << "\n" << "I am a C++ program" << std::endl; _getch(); } |
#include
<limits> #include <iostream> void wait() { //std::cout << "wait: press any key" << std::endl; std::cin.clear(); std::cin.ignore((std::numeric_limits<std::streamsize>::max)(), '\n'); std::cin.get(); } int main() { std::cout << "hello, world (Brian Kernighan 1974)" << "\n" << "I am a C++ program" << std::endl; wait(); } |
#include
<limits> #include <iostream> #include <string> void wait() { std::cout << "wait: press any key" << std::endl; std::cin.clear(); std::cin.ignore((std::numeric_limits<std::streamsize>::max)(), '\n'); std::cin.get(); } int main() { try { throw std::string ("Hallo Welt!"); } catch (std::string& s) { std::cout << s << std::endl; } wait(); } |
|
Kapselung: | Eigenschaften und Verhaltensweisen fasst man gekapselt in einem Objekt zusammen. |
Verbergen von Daten: | Die aus Außensicht wichtigen Funktionen sind zugänglich, alle anderern werden verborgen. |
Vererbung: | Man kann eine Kind-Klasse definieren, die eine Erweiterung einer schon bestehenden Klasse darstellt. |
Polymorphie: | Eine Verhaltensweise kann ihre Wirkungsweise ändern - abhängig von äußeren Ereignissen. |
//Testklasse
und Hilfsfunktionen #define NOMINMAX // due to conflict with max() #include <limits> #include <windows.h> #include <iostream> void wait() { std::cin.clear(); std::cin.ignore((std::numeric_limits<std::streamsize>::max)(), '\n'); std::cin.get(); } void textcolor(WORD color) { SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), color); } const int farbe1 = 11; const int farbe2 = 15; class xINT { private: int num; static int countCtor; static int countDtor; static int countCopycon; static int countOpAssign; public: xINT() { textcolor(farbe1); std::cout << this << ": " << "ctor" << std::endl; textcolor(farbe2); ++countCtor; } ~xINT() { textcolor(farbe1); std::cout << this << ": " << "dtor" << std::endl; textcolor(farbe2); ++countDtor; } xINT(const xINT& x) { textcolor(farbe1); std::cout << this << ": " << "copycon von " << std::dec << &x << std::endl; textcolor(farbe2); num = x.getNum(); ++countCopycon; } xINT& operator=(const xINT& x) { if (&x == this) { textcolor(farbe1); std::cout << "Selbstzuweisung mit op=" << std::endl; textcolor(farbe2); //return *this; //Schutz } textcolor(farbe1); std::cout << this << ": " << "op= von " << std::dec << &x << std::endl; textcolor(farbe2); num = x.getNum(); ++countOpAssign; return *this; } int getNum() const {return num;} void setNum(int val) {num = val;} static void statistik(std::ostream&); static void reset(); }; int xINT::countCtor = 0; int xINT::countDtor = 0; int xINT::countCopycon = 0; int xINT::countOpAssign = 0; void xINT::statistik(std::ostream& os) { textcolor(farbe1); os << "Ctor: " << countCtor << std::endl << "Dtor: " << countDtor << std::endl << "Copycon: " << countCopycon << std::endl << "op=: " << countOpAssign; textcolor(farbe2); } void xINT::reset() { countCtor = 0; countDtor = 0; countCopycon = 0; countOpAssign = 0; } std::ostream& operator<< (std::ostream& os, const xINT& x) { os << x.getNum(); return os; } std::istream& operator>> (std::istream& is, xINT& x) { int i; is >> i; x.setNum(i); return is; } bool operator< (const xINT& a, const xINT& b) { return a.getNum() < b.getNum(); } bool operator> (const xINT& a, const xINT& b) { return a.getNum() > b.getNum(); } bool operator== (const xINT& a, const xINT& b) { return a.getNum() == b.getNum(); } bool operator!= (const xINT& a, const xINT& b) { return a.getNum() != b.getNum(); } // Unser Testfeld int main() { { xINT i; wait(); } wait(); xINT::statistik(std::cout); wait(); } |
...
int main() { xINT *pi; { pi = new xINT; wait(); } wait(); delete pi; wait(); xINT::statistik(std::cout); wait(); } |
... int main() { xINT *pi; { pi = new xINT[5]; wait(); } wait(); delete[] pi; wait(); xINT::statistik(std::cout); wait(); } |
... class A : public xINT { private: double a; public: A(){std::cout << this << ": " << "A ctor" << std::endl;} ~A(){std::cout << this << ": " << "A dtor" << std::endl;} }; int main() { { A a; wait(); } wait(); xINT::statistik(std::cout); wait(); } |
... class A { private: double a; xINT i; public: A(){std::cout << this << ": " << "A ctor" << std::endl;} ~A(){std::cout << this << ": " << "A dtor" << std::endl;} }; int main() { { A a; wait(); } wait(); xINT::statistik(std::cout); wait(); } |
... class B { private: int b; public: B(){std::cout << this << ": " << "B ctor" << std::endl;} ~B(){std::cout << this << ": " << "B dtor" << std::endl;} }; class A : public B { private: double a; xINT i1; xINT i2; public: A(){std::cout << this << ": " << "A ctor" << std::endl;} ~A(){std::cout << this << ": " << "A dtor" << std::endl;} }; int main() { { A a; wait(); } wait(); xINT::statistik(std::cout); wait(); } |
... class A : public xINT { private: double a; public: A(){std::cout << this << ": " << "A ctor" << std::endl;} ~A(){std::cout << this << ": " << "A dtor" << std::endl;} }; class B : public xINT { private: double b; public: B(){std::cout << this << ": " << "B ctor" << std::endl;} ~B(){std::cout << this << ": " << "B dtor" << std::endl;} }; class D : public A, public B { private: double d; public: D(){std::cout << this << ": " << "D ctor" << std::endl;} ~D(){std::cout << this << ": " << "D dtor" << std::endl;} }; int main() { { D d; wait(); } wait(); xINT::statistik(std::cout); wait(); } |
int main() { { D d; std::cout << d.getNum() << std::endl; wait(); } wait(); xINT::statistik(std::cout); wait(); } |
int main() { { D d; std::cout << std::endl; std::cout << d.A::getNum() << std::endl; std::cout << d.B::getNum() << std::endl; wait(); } wait(); xINT::statistik(std::cout); wait(); } |
... class A : virtual public xINT { private: double a; public: A(){std::cout << this << ": " << "A ctor" << std::endl;} ~A(){std::cout << this << ": " << "A dtor" << std::endl;} }; class B : virtual public xINT { private: double b; public: B(){std::cout << this << ": " << "B ctor" << std::endl;} ~B(){std::cout << this << ": " << "B dtor" << std::endl;} }; class D : public B, public A { private: double d; public: D(){std::cout << this << ": " << "D ctor" << std::endl;} ~D(){std::cout << this << ": " << "D dtor" << std::endl;} }; int main() { { D d; std::cout << std::endl; std::cout << d.getNum() << std::endl; std::cout << d.A::getNum() << std::endl; std::cout << d.B::getNum() << std::endl; wait(); } wait(); xINT::statistik(std::cout); wait(); } |
... class A { public: A(xINT i){i_=i;} //Zuweisung im Konstruktor private: xINT i_; }; class B { public: B(xINT i):i_(i){} //Initialisierungsliste private: xINT i_; }; int main() { xINT i; i.setNum(42); wait(); { std::cout << "Klasse A:" << std::endl; A a(i); wait(); std::cout << "Klasse B:" << std::endl; B b(i); wait(); } wait(); } |
... #include <vector> #include <list> #include <deque> #include <algorithm> using namespace std; int main() { cout << "Container-Typ: " << "vector" << endl; vector<xINT> ct; // Hier Containertyp tauschen vector<xINT>::iterator it; // ... und hier den Iterator anpassen const int N = 1; //verändern xINT x; cout << endl << N << " mal push_back (hinten anhaengen)." << endl; for(size_t i=0; i<N; ++i) { x.setNum(i); ct.push_back(x); } cout << endl; for(it=ct.begin();it!=ct.end();++it) { cout << *it << endl; } cout << endl; xINT::statistik(cout); xINT::reset(); cout << endl << endl; cout << "Zahl 42 am Anfang einschieben." << endl; x.setNum(42); it = ct.begin(); ct.insert(it,x); cout << endl; for(it=ct.begin();it!=ct.end();++it) { cout << *it << endl; } cout << endl; xINT::statistik(cout); xINT::reset(); cout << endl << endl; cout << "Sortieren." << endl; sort(ct.begin(),ct.end()); //ct.sort(); cout << endl; for(it=ct.begin();it!=ct.end();++it) { cout << *it << endl; } cout << endl; xINT::statistik(cout); xINT::reset(); cout << endl << endl; wait(); } |
Ausgabe für N=1: | Ausgabe für N=2: |
Container-Typ: vector 0012FF4C: ctor 1 mal push_back (hinten anhaengen). 0012FEE0: copycon von 0012FF4C 00316498: copycon von 0012FEE0 0012FEE0: dtor 0 Ctor: 1 Dtor: 1 Copycon: 2 op=: 0 Zahl 42 am Anfang einschieben. 0012FF08: copycon von 0012FF4C 003164A8: copycon von 0012FF08 003164AC: copycon von 00316498 00316498: dtor 0012FF08: dtor 42 0 Ctor: 0 Dtor: 2 Copycon: 3 op=: 0 Sortieren. 0012FF04: copycon von 003164AC 003164AC: op= von 003164A8 003164A8: op= von 0012FF04 0012FF04: dtor 0 42 Ctor: 0 Dtor: 1 Copycon: 1 op=: 2 |
Container-Typ: vector 0012FF48: ctor 2 mal push_back (hinten anhaengen). 0012FEE0: copycon von 0012FF48 00316498: copycon von 0012FEE0 0012FEE0: dtor 0012FEE0: copycon von 0012FF48 003164A8: copycon von 00316498 003164AC: copycon von 0012FEE0 00316498: dtor 0012FEE0: dtor 0 1 Ctor: 1 Dtor: 3 Copycon: 5 op=: 0 Zahl 42 am Anfang einschieben. 0012FF08: copycon von 0012FF48 003164B8: copycon von 0012FF08 003164BC: copycon von 003164A8 003164C0: copycon von 003164AC 003164A8: dtor 003164AC: dtor 0012FF08: dtor 42 0 1 Ctor: 0 Dtor: 3 Copycon: 4 op=: 0 Sortieren. 0012FF04: copycon von 003164BC 003164BC: op= von 003164B8 003164B8: op= von 0012FF04 0012FF04: dtor 0012FF04: copycon von 003164C0 003164C0: op= von 003164BC 003164BC: op= von 0012FF04 0012FF04: dtor 0 1 42 Ctor: 0 Dtor: 2 Copycon: 2 op=: 4 |
xINT( const
xINT& x
) { num = x.getNum();
} (blau: Original, rot: Kopie) |
//... int main() { cout << "Container-Typ: " << "list" << endl; list<xINT> ct; // Hier Containertyp tauschen list<xINT>::iterator it; // ... und hier den Iterator anpassen const int N = 2; xINT x; cout << endl << N << " mal push_back (hinten anhaengen)." << endl; for(size_t i=0; i<N; ++i) { x.setNum(i); ct.push_back(x); } cout << endl; for(it=ct.begin();it!=ct.end();++it) { cout << *it << endl; } cout << endl; xINT::statistik(cout); xINT::reset(); cout << endl << endl; cout << "Zahl 42 am Anfang einschieben." << endl; x.setNum(42); it = ct.begin(); ct.insert(it,x); cout << endl; for(it=ct.begin();it!=ct.end();++it) { cout << *it << endl; } cout << endl; xINT::statistik(cout); xINT::reset(); cout << endl << endl; cout << "Sortieren." << endl; //sort(ct.begin(),ct.end()); ct.sort(); //für list diese Anweisung verwenden! cout << endl; for(it=ct.begin();it!=ct.end();++it) { cout << *it << endl; } cout << endl; xINT::statistik(cout); xINT::reset(); cout << endl << endl; wait(); } |
Hinten-Anhängen: | Ctor:
1 Dtor: 0 Copycon: 10000000 op=: 0 |
Vorne-Reinschieben | Ctor:
0 Dtor: 0 Copycon: 1 op=: 0 |
Sortieren |
Ctor:
0 Dtor: 0 Copycon: 0 op=: 0 |
cout
<< "Container-Typ: " << "deque" << endl; deque<xINT> ct; // Hier Containertyp tauschen deque<xINT>::iterator it; // ... und hier den Iterator anpassen //... sort(ct.begin(),ct.end()); |
... #include <vector> #include <list> #include <deque> #include <algorithm> using namespace std; int main() { cout << "Container-Typ: " << "vector" << endl; vector<xINT> ct, ct1; // Hier Containertyp tauschen vector<xINT>::iterator it; // ... und hier den Iterator anpassen const int N = 10; xINT x; cout << endl << N << " mal push_back (hinten anhaengen)." << endl; for(size_t i=0; i<N; ++i) { x.setNum(i); ct.push_back(x); } cout << endl; for(it=ct.begin();it!=ct.end();++it) { cout << *it << endl; } cout << endl; xINT::statistik(cout); xINT::reset(); cout << endl << endl; cout << "Container komplett neu zuweisen" << endl; ct1 = ct; cout << endl; xINT::statistik(cout); xINT::reset(); cout << endl << endl; wait(); } |
//... int main() { cout << "Container-Typ: " << "vector" << endl; vector<xINT> ct, ct1; // Hier Containertyp tauschen vector<xINT>::iterator it; // ... und hier den Iterator anpassen const int N = 10; xINT x; ct.reserve(N); //Speicherplatz vorab reservieren für N Elemente cout << endl << N << " mal push_back (hinten anhaengen)." << endl; for(size_t i=0; i<N; ++i) { x.setNum(i); ct.push_back(x); } cout << endl; //... |
xINT&
operator= ( const xINT& x ) { if (&x == this) { std::cout << "Selbstzuweisung mit op=" << std::endl; } num = x.getNum(); return *this; } (blau: Original, rot: Kopie mit gleichzeitiger Überschreibung eines hoffentlich(!) nicht mehr benötigten Objektes) |
... int main() { { xINT i1, i2; i1.setNum(42); i2 = i1; std::cout << i1.getNum() << " " << i2.getNum() << std::endl; wait(); } wait(); } |
... int main() { { xINT i1; i1.setNum(42); i1 = i1; std::cout << i1.getNum() << std::endl; wait(); } wait(); } |
xINT&
operator=(const xINT& x) { if (&x == this) // Quelle und Ziel identisch ==> Selbstzuweisung!!! { #ifdef _TEST_ //textcolor(farbe1); std::cout << this << ": Achtung! Selbstzuweisung mit op=" << std::endl; //textcolor(farbe2); #endif ++countOpAssign; return *this; //Schutz } #ifdef _TEST_ //textcolor(farbe1); std::cout << this << ": " << "op= von " << std::dec << &x << std::endl; //textcolor(farbe2); #endif num = x.getNum(); ++countOpAssign; return *this; } |
std::ostream& operator<<
(std::ostream& os, const xINT& x) { os << x.getNum(); return os; } std::istream& operator>> (std::istream& is, xINT& x) { int i; is >> i; x.setNum(i); return is; } |
... #include <fstream> #include <vector> #include <algorithm> using namespace std; int main() { { const int N = 10; xINT x; //ctor der Testklasse xINT in Aktion vector<xINT> ct; //Container ct.reserve(N); //Wichtig für die Effizienz! for(int i=0; i<N; ++i) { x.setNum(i); ct.push_back(x); //copycon der Testklasse xINT in Aktion } //Speichervorgang in File fstream file("output.txt", ios::out); if(!file) { cout << "Datei konnte nicht erzeugt/geoeffnet werden" << endl; return 2; //ERROR_FILE_NOT_FOUND } file << ct.size() << " "; //Wichtig für ein späteres ct.reserve(...) beim Lesen copy( ct.begin(), ct.end(), ostream_iterator<xINT>(file," ") ); file.close(); wait(); } //dtor der Testklasse xINT in Aktion xINT::statistik(cout); xINT::reset(); wait(); return 0; } |
... #include <fstream> #include <vector> #include <algorithm> using namespace std; int main() { const int N = 10; xINT x; //ctor der Testklasse xINT in Aktion vector<xINT> ct; //Container ct.reserve(N); //Wichtig für die Effizienz! for(int i=0; i<N; ++i) { x.setNum(i); ct.push_back(x); //copycon der Testklasse xINT in Aktion } cout << "\nSpeichern in File\n" << endl; fstream file("output.txt", ios::out); if(!file) { cout << "Datei konnte nicht erzeugt/geoeffnet werden" << endl; return 2; //ERROR_FILE_NOT_FOUND } file << ct.size() << " "; //Wichtig für ein späteres ct.reserve(...) beim Lesen falls notwendig copy( ct.begin(), ct.end(), ostream_iterator<xINT>(file," ") ); file.close(); xINT::statistik(cout); xINT::reset(); wait(); cout << "\nLesen aus File\n" << endl; file.open("output.txt",ios::in); if(!file) { cout << "Datei konnte nicht geoeffnet werden" << endl; return 2; //ERROR_FILE_NOT_FOUND } unsigned int size; file >> size; cout << "\nAnzahl: " << size << endl; cout << "\nct.clear\n" << endl; ct.clear(); wait(); xINT::statistik(cout); xINT::reset(); wait(); cout << "\nistream_iterator\n" << endl; istream_iterator<xINT> begin(file); // Anfangsiterator auf die Datei istream_iterator<xINT> end; // Enditerator auf die Datei cout << "\ncopy nach ct\n" << endl; copy( begin, end, back_inserter(ct) ); cout << "\ncopy nach cout\n" << endl; copy(ct.begin(), ct.end(), ostream_iterator<xINT>(cout," ") ); cout << endl; wait(); xINT::statistik(cout); xINT::reset(); wait(); return 0; } |
... #include <cassert> using namespace std; const int N = 4; template <class T> class MyStack { private: T elements[N]; int top_; public: MyStack(); ~MyStack(); void push(T i); //Element eingeben T peek(); //Element lesen void pop(); //Element entfernen bool empty(); //MyStack leer? }; template <class T> MyStack<T>::MyStack() { top_=-1; }; template <class T> MyStack<T>::~MyStack(){}; template <class T> T MyStack<T>::peek() { return elements[top_];} template <class T> bool MyStack<T>::empty() { return top_ == -1;} template <class T> void MyStack<T>::push(T i) { assert( top_ < N-1 ); ++top_; elements[top_] = i; } template <class T> void MyStack<T>::pop() { assert(top_ > -1); --top_; } int main() { MyStack<xINT> stack; xINT x; cout << "\nMyStack wird gefuellt\n" << endl; for (int i=1; i<N; ++i) { x.setNum(i); stack.push(x); cout << stack.peek() << endl; } cout << "\nMyStack wird entleert\n" << endl; while ( stack.empty() == false ) { cout << stack.peek() << endl; stack.pop(); } wait(); return 0; } |
const
int N = ...; template <class T> class MyStack { private: T elements[N]; int top_; public: MyStack(); ~MyStack(); void push(const T& i); //Element eingeben const T& peek() const; //Element lesen void pop(); //Element entfernen bool empty() const; //MyStack leer? }; template <class T> MyStack<T>::MyStack() { top_=-1; }; template <class T> MyStack<T>::~MyStack() {}; template <class T> const T& MyStack<T>::peek() const { return elements[top_];} template <class T> bool MyStack<T>::empty() const { return top_ == -1;} template <class T> void MyStack<T>::push(const T& i) { assert( top_ < N-1 ); ++top_; elements[top_] = i; } template <class T> void MyStack<T>::pop() { assert(top_ > -1); --top_; } |
... #include <stack> int main() { { stack<xINT> stack; xINT x; cout << "\nstd::stack wird gefuellt\n" << endl; for (int i=1; i<N; ++i) { x.setNum(i); stack.push(x); cout << stack.top() << endl; } cout << "\nstd::stack wird entleert\n" << endl; while ( stack.empty() == false ) { cout << stack.top() << endl; stack.pop(); } wait(); } wait(); return 0; } |
... #include <cassert> using namespace std; const int N = 4; //Maximale Groesse des Stacks template <class T> class MyStack { private: T* elements; int top_; public: MyStack(int n); ~MyStack(); void push(const T& i); //Element eingeben const T& peek() const; //Element lesen void pop(); //Element entfernen bool empty() const; //MyStack leer? }; template <class T> MyStack<T>::MyStack(int n) { top_=-1; elements = new T[n]; }; template <class T> MyStack<T>::~MyStack(){delete[] elements;}; template <class T> const T& MyStack<T>::peek() const { return elements[top_];} template <class T> bool MyStack<T>::empty() const { return top_ == -1;} template <class T> void MyStack<T>::push(const T& i) { assert( top_ < N-1 ); ++top_; elements[top_] = i; } template <class T> void MyStack<T>::pop() { assert(top_ > -1); --top_; } int main() { { MyStack<xINT> stack(N); xINT x; cout << "\nMyStack wird gefuellt\n" << endl; for (int i=1; i<=N; ++i) { x.setNum(i); stack.push(x); cout << stack.peek() << endl; } cout << "\nMyStack wird entleert\n" << endl; while ( stack.empty() == false ) { cout << stack.peek() << endl; stack.pop(); } wait(); } wait(); return 0; } |
... #include <deque> using namespace std; template <class T> class Stack { private: std::deque<T> ct; //Umhuellter Container public: void push (const T& i) { ct.push_back(i); } void pop() { ct.pop_back(); } const T& peek() const { return ct.back(); } bool empty() const { return ct.empty(); } }; int main() { { Stack<xINT> stack; xINT x; cout << "\nStack wird gefuellt\n" << endl; for (int i=1; i<4; ++i) { x.setNum(i); stack.push(x); cout << stack.peek() << endl; } cout << "\nStack wird entleert\n" << endl; while ( stack.empty() == false ) { cout << stack.peek() << endl; stack.pop(); } wait(); } wait(); return 0; } |
class
Stack { private: std::list<T> ct; //Umhuellter Container public: void push (const T& i) { ct.push_back(i); } void pop() { ct.pop_back(); } const T& peek() const { return ct.back(); } bool empty() const { return ct.empty(); } }; |
template
<class T, class Container = deque<T>> class Stack { private: Container ct; // Umhuellter Container public: void push (const T& i) { ct.push_back(i); } void pop() { ct.pop_back(); } const T& peek() const { return ct.back(); } bool empty() const { return ct.empty(); } }; //jetzt geht z.B.: int main() { { Stack<xINT,vector<xINT>> stack; xINT x; //... |
int
main() { const int N = 5000000; clock_t t1,t2; double ts; xINT x; { Stack<xINT,list<xINT>> stackL; t1 = clock(); //start cout << "\nStackL wird gefuellt\n" << endl; for (int i=1; i<=N; ++i) { x.setNum(i); stackL.push(x); stackL.peek(); } cout << "\nStackL wird entleert\n" << endl; while ( stackL.empty() == false ) { stackL.peek(); stackL.pop(); } t2 = clock(); //end ts = (t2-t1)/static_cast<float>(CLOCKS_PER_SEC); //time span in seconds cout << "time stackL: " << ts << " sec" << endl; } wait(); { Stack<xINT> stackD; t1 = clock(); //start cout << "\nStackD wird gefuellt\n" << endl; for (int i=1; i<=N; ++i) { x.setNum(i); stackD.push(x); stackD.peek(); } cout << "\nStackD wird entleert\n" << endl; while ( stackD.empty() == false ) { stackD.peek(); stackD.pop(); } t2 = clock(); //end ts = (t2-t1)/static_cast<float>(CLOCKS_PER_SEC); //time span in seconds cout << "time stackD: " << ts << " sec" << endl; } wait(); return 0; } |
int main() { const int N = 10000000; clock_t t1,t2; double ts; xINT x; cout << "N = " << N << '\n' << endl; { Stack<xINT,vector<xINT>> stackV; cout << "\nStackV wird gefuellt\n" << endl; t1 = clock(); //start for (int i=1; i<=N; ++i) { x.setNum(i); stackV.push(x); } t2 = clock(); //end ts = (t2-t1)/static_cast<float>(CLOCKS_PER_SEC); //time span in seconds cout << "time stackV: " << ts << " sec" << endl; } wait(); xINT::statistik(cout); xINT::reset(); wait(); { Stack<xINT> stackD; cout << "\nStackD wird gefuellt\n" << endl; t1 = clock(); //start for (int i=1; i<=N; ++i) { x.setNum(i); stackD.push(x); } t2 = clock(); //end ts = (t2-t1)/static_cast<float>(CLOCKS_PER_SEC); //time span in seconds cout << "time stackD: " << ts << " sec" << endl; } wait(); xINT::statistik(cout); xINT::reset(); wait(); return 0; } |
<algorithm>
-- (STL) for defining numerous templates that implement useful
algorithms<deque>
-- (STL) for defining a template class that implements a deque container<functional>
-- (STL) for defining several templates that help construct predicates
for the templates defined<iterator>
-- (STL) for defining several templates that help define and manipulate
iterators<list>
-- (STL) for defining a template class that implements
a doubly linked list container<map>
-- (STL) for defining template classes that implement associative
containers
that map keys to values<memory>
-- (STL) for defining several templates that allocate and free storage
for various container classes<numeric>
-- (STL) for defining several templates that implement useful numeric
functions<queue>
-- (STL) for defining a template class that implements a queue container<set>
-- (STL) for defining template classes that implement associative
containers<stack>
-- (STL) for defining a template class that implements a stack container<utility>
-- (STL) for defining several templates of general utility<vector>
-- (STL) for defining a template class that implements a vector
container<unordered_map>
-- (STL) for defining template classes that implement unordered
associative containers that map keys to values<unordered_set>
-- (STL) for defining template classes that implement unordered
associative containers<hash_map>
-- (STL) for defining template classes that implement hashed
associative containers that map keys to values (includes
an STLport-compatible adapter)<hash_set>
-- (STL) for defining template classes that implement hashed
associative containers (also includes an STLport-compatible adapter)<slist>
-- (STL) for defining a template class that implements
a singly linked list container... #include <memory> //auto_ptr int main() { { xINT* p1(new xINT); //oder: xINT* p1 = new xINT; delete p1; } wait(); { std::auto_ptr<xINT> p2(new xINT); //nicht: std::auto_ptr<xINT> p2 = new xINT; //falsch!!! } wait(); return 0; } |
... #include <memory> int main() { { xINT* p1(new xINT[3]); delete[] p1; } wait(); { std::auto_ptr<xINT> p2(new xINT[3]); //falsch!!! } wait(); return 0; } |
... #include <memory> using namespace std; int main() { { auto_ptr<xINT> p1(new xINT); p1->setNum(333); cout << p1->getNum() << endl; auto_ptr<xINT> p2 = p1; //Das Objekt geht hier von p1 an p2 ueber p2->setNum(42); cout << p2->getNum() << endl; cout << *p2 << endl; cout << p1.get() << endl; cout << p2.get() << endl; } wait(); return 0; } |
... #include <vector> using namespace std; int main() { vector<int>v(1000000000); //10^9 Elemente wait(); return 0; } |
... #include <vector> using namespace std; int main() { try { vector<int>v(1000000000); } catch(...) { cout << "Fehler" << endl; } wait(); return 0; } |
... #include <vector> using namespace std; class std::exception; int main() { try { vector<int>v(1000000000); } catch(exception& e) { cout << "exception" << endl; } //Fangen per Referenz! catch(...) { cout << "Fehler" << endl; } wait(); return 0; } |
Basisklasse: Abgeleitete Klassen:
exception
|
... #include <vector> #include <exception> using namespace std; int main() { try { vector<int>v(1000000000); } catch(exception& e) { cout << typeid(e).name( ) << endl; cout << e.what() << endl; } wait(); return 0; } |
... #include <vector> #include <exception> using namespace std; int main() { try { vector<int>v(1000000000); } catch(bad_alloc& e) { cout << "Gefangener vom Typ bad_alloc: " << e.what() << endl; } catch(exception& e) { cout << "Gefangener vom Typ exception: " << e.what() << endl; } wait(); return 0; } |
... #include <exception> using namespace std; int main() { try { throw "Hallo Welt!"; } catch(bad_alloc& e) { cout << "Gefangener vom Typ bad_alloc: " << e.what() << endl; } catch(exception& e) { cout << "Gefangener vom Typ exception: " << e.what() << endl; } catch(char* str) { cout << str << endl; } catch(...) { cout << "Ich bin der (Fast-)Allesfaenger" << endl; } wait(); return 0; } |
... #include <string> using namespace std; int main() { try { throw string("Hallo Welt!"); } catch(char* str) { cout << "char*: " << str << endl; } catch(string& str) { cout << "string: " << str << endl; } catch(...) { cout << "Ich bin der (Fast-)Allesfaenger" << endl; } wait(); return 0; } |
... #include <vector> class exception; using namespace std; int main() { try { try { vector<int>v(1000000000); } catch(bad_alloc&) { cout << "Ich werfe den Fehler bad_alloc weiter." << endl; throw; } } catch(bad_alloc&) { cout << "Ich fange den Fehler bad_alloc auf."; } wait(); return 0; } |
... #include <vector> class exception; using namespace std; void function() { try { vector<int>v(1000000000); } catch(bad_alloc&) { cout << "Ich werfe den Fehler bad_alloc weiter." << endl; throw; } } int main() { try { function(); //beinhaltet den inneren try/catch/throw-Block } catch(bad_alloc&) { cout << "Ich fange den Fehler bad_alloc auf."; } wait(); return 0; } |
//wie
oben void function() throw (bad_alloc) { //wie oben } int main() { // wie oben } |
//wie
oben void function() throw () //kein Fehlertyp darf geworfen werden { //wie oben } int main() { // wie oben } |
... #include <deque> #include <ctime> #include <cstring> #include <cstdlib> #include <string> #include <iostream> using namespace std ; /************************** Subjekt und Beobachter ***********************************/ class Subject; struct Observer { virtual void Update( Subject* ) = 0; }; class Subject { public: void Attach( Observer* ); void Detach( Observer* ); void Notify(); private: deque<Observer*> observers_; }; void Subject::Attach( Observer* o ) //MeldeAn { observers_.push_back(o); } void Subject::Detach( Observer* o ) //MeldeAb { size_t n = observers_.size(); size_t i; for( i = 0; i < n; ++i ) { if(observers_[i] == o) break; } if(i < n) observers_.erase( observers_.begin() + i ); } void Subject::Notify() //Benachrichtige { size_t n = observers_.size(); for( size_t i = 0; i < n; ++i ) observers_[i]->Update(this); } /************************** Konkretes Subjekt ***********************************/ class Timer : public Subject { public: Timer() { _strtime_s( buffer_ ); }; std::string Timer::GetTime()const {return std::string(buffer_);} void Tick(); private: char buffer_[128]; }; void Timer::Tick() { _tzset(); _strtime_s( buffer_ ); Notify(); } /************************** Konkreter Beobachter ***********************************/ class Clock: public Observer { public: Clock( std::string name, Timer* ); ~Clock(); void Update( Subject* ); std::string getName() const {return name_;} Timer* getSubject() const {return subject_;} private: std::string name_; Timer* subject_; }; Clock::Clock( std::string name, Timer* s ) : subject_(s) { name_ = name; subject_->Attach(this); } Clock::~Clock () { subject_->Detach(this); } void Clock::Update( Subject* s ) //Aktualisiere { if( s == subject_ ) cout << getName() << " zeigt " << subject_->GetTime() << endl; } /************************** Hauptprogramm ***********************************/ int main() { Timer t; //Subjekt const int N = 100; char buffer[20]; Clock* pC[N]; for(int i=0; i<N; ++i) { _itoa_s( i, buffer, 10 ); pC[i] = new Clock( buffer, &t ); //Observer } t.Tick(); wait(); for(int i=0; i<N/2; ++i) { pC[i]->getSubject()->Detach(pC[i]); //Einige Observer melden sich ab } t.Tick(); wait(); for(int i=0; i<N; ++i) { delete pC[i]; } } |
... #include <deque> #include <string> #include <ostream> /************************** Subjekt und Beobachter ***********************************/ class Subject; struct Observer { virtual void update( Subject* ) = 0; }; class Subject { public: void attach( Observer* ); void detach( Observer* ); void notify(); private: std::deque<Observer*> observers_; }; void Subject::attach( Observer* o ) //MeldeAn { observers_.push_back(o); } void Subject::detach( Observer* o ) //MeldeAb { size_t n = observers_.size(); size_t i; for( i = 0; i < n; ++i ) { if(observers_[i] == o) break; } if(i < n) observers_.erase( observers_.begin() + i ); } void Subject::notify() //Benachrichtige { size_t n = observers_.size(); for( size_t i = 0; i < n; ++i ) observers_[i]->update(this); } /************************** Konkretes Subjekt ***********************************/ class MailServer : public Subject { public: MailServer( std::string name ): name_(name){} void neuerNewsletter() { notify(); } std::string getName() const {return name_;} private: const std::string name_; }; /************************** Konkreter Beobachter ***********************************/ class EmailKonto: public Observer { public: EmailKonto( std::string name, MailServer* ); ~EmailKonto(); void update( Subject* ); std::string getName() const {return name_;} MailServer* getSubject() const {return subject_;} private: const std::string name_; MailServer* subject_; }; EmailKonto::EmailKonto( std::string name, MailServer* s ) : name_(name), subject_(s) { subject_->attach(this); } EmailKonto::~EmailKonto () { subject_->detach(this); } void EmailKonto::update( Subject* s ) //Aktualisiere { if( s == subject_ ) std::cout << "Hallo Herr Nr. " << getName() << ", ein neuer Newsletter von " << subject_->getName()<< " ist erschienen." << std::endl; } /************************** Hauptprogramm ***********************************/ int main() { MailServer s("HenkesSoft3000"); //Subjekt "MailServer" const int N = 5; char buffer[10]; EmailKonto* pMK[N]; for(int i=0; i<N; ++i) { _itoa_s( i, buffer, 10 ); pMK[i] = new EmailKonto( buffer, &s ); //Mailkonten melden sich an } s.neuerNewsletter(); wait(); for(int i=0; i<(N-2); ++i) { pMK[i]->getSubject()->detach(pMK[i]); //Zwei Mailkonten melden sich ab } s.neuerNewsletter(); wait(); for(int i=0; i<N; ++i) { delete pMK[i]; } } |
//
MySingleton.h
class MySingleton |
// MySingleton.h class MySingleton : public Singleton<Klasse_fuer_vereinzelte_Objekte> |