C++ für Fortgeschrittene |
|
ISO/IEC 14882:2003
specifies requirements for implementations of the
C++ programming language and standard library. By implication, it also
defines C++ programs and their behavior. C++ is a general-purpose programming language based on the C
programming language as described in ISO/IEC
9899:1999. In addition to
the facilities provided by C, C++ provides
|
| <algorithm>
<iomanip> <list>
<ostream> <streambuf> <bitset> <ios> <locale> <queue> <string> <compex> <iosfwd> <map> <set> <typeinfo> <deque> <iostream> <memory> <sstream> <utility> <exception> <istream> <new> <stack> <valarray> <fstream> <iterator> <numeric> <stdexcept> <vector> <functinoal> <limits> |
Gemäß C++-Standard gibt es drei portable und korrekte Versionen der für die "Konsole" verwendeten Einstiegsfunktion main():
|
Der Rückgabewert int ist inzwischen zwingend erforderlich.
Man kann - muss aber nicht - main() mit einer return Anweisung beenden. C++ definiert hier freundlicherweise ein implizites return 0; am Ende von main(). Dies führt oft zu kontroversen Diskussionen in C++-Foren, ob denn nun ein return notwendig sei oder nicht.
Die Antwort ist eindeutig: Moderne Compiler benötigen es nicht mehr!
C++ macht aufgrund der höheren Freiheitsgrade vielen Anfängern Probleme, weil in gewissen Fällen nicht durch Verbote, Warn- oder Fehlermeldungen Grenzen gesetzt werden. Dieses höhere Maß an Verantwortung wird heute eher negativ gesehen. Hier findet sich dazu ein interessanter Aufsatz über die Verwendung von C++ in der Schule.
Man muss zugeben, dass viele dieser Argumente treffend sind. C++ ist nicht "idiotensicher". Daher sollte man die aufgestellten Fallgruben genau kennen.
| /*** stdafx.h ***/ #pragma once #define WIN32_LEAN_AND_MEAN #include <stdio.h> #include <tchar.h> |
| /*** main.cpp ***/ #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { return 0; } |
| #include
"stdafx.h" #include <conio.h> int _tmain(int argc, _TCHAR* argv[]) { getch(); return 0; } |
| #include
"stdafx.h" #include <iostream> void wait() { std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); std::cin.get(); } int _tmain(int argc, _TCHAR* argv[]) { wait(); return 0; } |
| /*** stdafx.h ***/ #define WIN32_LEAN_AND_MEAN #include <cstdio> #include <tchar.h> #include <iostream> void wait(); |
| /*** stdafx.cpp ***/ #include "stdafx.h" void wait() { std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); std::cin.get(); } |
| /*** main.cpp ***/ #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { wait(); return 0; } |
| #include
"stdafx.h" #include <string> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { try { throw string("Hallo Welt!"); } catch ( string& s) { cout << s << endl; } wait(); return 0; } |
|
| /*** stdafx.h ***/ #define WIN32_LEAN_AND_MEAN #include <cstdio> #include <tchar.h> #include <iostream> inline void wait() { std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); std::cin.get(); } |
| /*** stdafx.cpp ***/ #include "stdafx.h" |
| /*** main.cpp ***/ #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { wait(); return 0; } |
| /*** stdafx.h ***/ #define WIN32_LEAN_AND_MEAN #include <cstdio> #include <tchar.h> #include <iostream> void wait(); //nicht inline namespace My { extern const double PI; } |
/*** stdafx.cpp ***/ #include "stdafx.h" void wait() { /*...*/ } const double My::PI = 3.1415926535897932384626433832795; |
/*** main.cpp ***/ #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { std::cout << My::PI << std::endl; wait(); return 0; } |
Creating temporary file "..." with contents
[
/O2 /GL /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE"
/FD /EHsc /MD /Yu"stdafx.h" /Fp"Release\main.pch" /Fo"Release\\"
/Fd"Release\vc80.pdb" /W3 /c /Wp64 /Zi /TP ".\wait.cpp"
]
Creating command line "cl.exe @"..." /nologo /errorReport:prompt"
Creating temporary file "..." with contents
[
/O2 /GL /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE"
/FD /EHsc /MD /Yc"stdafx.h" /Fp"Release\main.pch" /Fo"Release\\"
/Fd"Release\vc80.pdb" /W3 /c /Wp64 /Zi /TP ".\stdafx.cpp"
]
Creating command line "cl.exe @"...\Release\..." /nologo /errorReport:prompt"
Creating temporary file "...\Release\..." with contents
[
/OUT:"...\Release\wait.exe"
/INCREMENTAL:NO /MANIFEST /MANIFESTFILE:"Release\main.exe.intermediate.manifest"
/DEBUG /PDB:"...\release\main.pdb" /SUBSYSTEM:CONSOLE /OPT:REF /OPT:ICF /LTCG
/MACHINE:X86 kernel32.lib
".\release\stdafx.obj"
".\release\main.obj"
]
Creating command line "link.exe @"...\Release\..." /NOLOGO /ERRORREPORT:PROMPT"
Creating temporary file "...\Release\..." with contents
[
/outputresource:"..\release\main.exe;#1" /manifest
".\release\main.exe.intermediate.manifest"
]
Creating command line "mt.exe @"...\Release\..." /nologo"
Creating temporary file "...\Release\....bat" with contents
[
@echo Manifest resource last updated at %TIME% on %DATE% > ".\release\mt.dep"
]
Creating command line """...\Release\....bat"""
Der Compiler erzeugt aus den Sourcecodedateien xxx.cpp sogenannte Objektdateien xxx.o, die anschließend vom Linker unter Einbindung weiterer Bibliotheken als ausführbare Datei (main.exe) ausgegeben werden.Compiling...
stdafx.cpp
Compiling...
main.cpp
Linking...
Generating code
Finished generating code
Embedding manifest...
| Option | Purpose |
|---|---|
|
Specifies a response file |
|
|
Lists the compiler options |
|
|
Specifies a directory to search to resolve file references
passed to the |
|
|
Enable code analysis. |
|
|
Use SSE or SSE2 instructions in code generation (x64 only) |
|
|
Increases the number of addressable sections in an .obj file. |
|
|
Preserves comments during preprocessing |
|
|
Compiles without linking |
|
|
Produces an output file to run on the common language runtime |
|
|
Defines constants and macros |
|
|
Process documentation comments to an XML file. |
|
|
Copies preprocessor output to standard output |
|
|
Specifies the model of exception handling |
|
|
Copies preprocessor output to standard output |
|
|
Allows you to provide internal compiler error (ICE) information directly to the Visual C++ team. |
|
|
Sets stack size |
|
|
Produces code that is optimized for a specific x64 architecture or for the specifics of micro-architectures in both the AMD64 and Extended Memory 64 Technology (EM64T) architectures. |
|
|
Creates a listing file |
|
|
Sets listing file name |
|
|
Display full path of source code files passed to cl.exe in diagnostic text. |
|
|
Renames program database file |
|
|
Renames the executable file |
|
|
Preprocesses the specified include file |
|
|
Creates a mapfile |
|
|
Creates an object file |
|
|
Specify floating-point behavior. |
|
|
Specifies a precompiled header file name |
|
|
Generates browser files |
|
|
Forces the use of a file name as if it had been passed to the |
|
|
Merges injected code with source file |
|
|
Optimize for Itanium processor. vOnly available in the IPF cross compiler or IPF native compiler. |
|
|
Optimize for Itanium2 processor (default between /G1 and /G2). Only available in the IPF cross compiler or IPF native compiler. |
|
|
Optimizes code for Windows application |
|
|
Uses the __cdecl calling convention (x64 only) |
|
|
Activates stack probes |
|
|
Enables string pooling |
|
|
Calls hook function _pexit |
|
|
Calls hook function _penter |
|
|
Enables whole program optimization |
|
|
Enables minimal rebuild |
|
|
Enables run-time type information (RTTI) |
|
|
Uses the __fastcall calling convention (x64 only) |
|
|
Buffers security check |
|
|
Controls stack probes |
|
|
Supports fiber safety for data allocated using static thread-local storage |
|
|
Enables synchronous exception handling |
|
|
Enables function-level linking |
|
|
Same as /RTC1 |
|
|
Uses the __stdcall calling convention (x64 only) |
|
|
Restricts the length of external (public) names |
|
|
Lists the compiler options |
|
|
Forces parameters passed in registers to be written to their locations on the stack upon function entry. This compiler option is only for the x64 compilers (native and cross compile). |
|
|
Creates a hotpatchable image. |
|
|
Searches a directory for include files |
|
|
Changes the default char type |
|
|
Creates a dynamic-link library |
|
|
Creates a debug dynamic-link library |
|
|
Passes the specified option to LINK |
|
|
Creates an MSIL module. |
|
|
Creates a multithreaded DLL using MSVCRT.lib |
|
|
Creates a debug multithreaded DLL using MSVCRTD.lib |
|
|
Creates a multithreaded executable file using LIBCMT.lib |
|
|
Creates a debug multithreaded executable file using LIBCMTD.lib |
|
|
Suppresses display of sign-on banner |
|
|
Creates small code |
|
|
Creates fast code |
|
|
Controls inline expansion |
|
|
Disables optimization |
|
|
Uses global optimizations |
|
|
Generates intrinsic functions |
|
|
Enables |
|
|
Favors small code |
|
|
Favors fast code |
|
|
Uses maximum optimization (/Ob2gity /Gs) |
|
|
Omits frame pointer (x86 only) |
|
|
Suppresses _ftol when a conversion from a floating-point type to an integral type is required (x64 only) |
|
|
Does not generate sequences of instructions that give unexpected results, according to the errata for the B CPU stepping. (IPF only) |
|
|
Does not generate sequences of instructions that give unexpected results, according to the errata for the C CPU stepping. (IPF only) |
|
|
Do not use upper 96 floating-point registers. (IPF only) |
|
|
Generates an image with position dependent code (IPF only). |
|
|
Enhances performance for programs that do not create functions at runtime. (IPF only) |
|
|
Writes preprocessor output to a file |
|
|
Enables run-time error checking |
|
|
Displays a list of include files during compilation |
|
|
Specifies a C source file |
|
|
Specifies a C++ source file |
|
|
Removes a predefined macro |
|
|
Removes all predefined macros |
|
|
Sets the version string |
|
|
Suppresses or enables hidden vtordisp class members |
|
|
Uses best base for pointers to members |
|
|
Uses full generality for pointers to members |
|
|
Declares multiple inheritance |
|
|
Declares single inheritance |
|
|
Declares virtual inheritance |
|
|
Sets warning level |
|
|
Disables all warnings |
|
|
Enables all warnings, including warnings that are disabled by default |
|
|
Enables one-line diagnostics for error and warning messages when compiling C++ source code from the command line |
|
|
Detects 64-bit portability problems |
|
|
Ignores the standard include directory |
|
|
Ignores all other precompiled-header compiler options in the current build |
|
|
Creates a precompiled header file |
|
|
Places complete debugging information in all object files |
|
|
Injects a PCH reference when creating a debug library |
|
|
Uses a precompiled header file during build |
|
|
Generates C 7.0–compatible debugging information |
|
|
Disables language extensions |
|
|
Specifies standard behavior under /Ze |
|
|
Enables language extensions |
|
|
Generates function prototypes |
|
|
Includes debug information in a program database compatible with Edit and Continue |
|
|
Generates complete debugging information |
|
|
Removes default library name from .obj file (x64 only) |
|
|
Specifies the precompiled header memory allocation limit |
|
|
Packs structure members |
|
|
Checks syntax only |
|
|
Generates debuggable optimized code. Only available in the IPF cross compiler or IPF native compiler. |
O2 Creates fast code/O2 /GL /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE"
/FD /EHsc /MD /Yu"stdafx.h" /Fp"Release\main.pch" /Fo"Release\\"
/Fd"Release\vc80.pdb" /W3 /c /Wp64 /Zi /TP ".\wait.cpp"
| int
_tmain( /* int argc, _TCHAR*
argv[] */ ) { std::cout << My::PI << std::endl; wait(); return 0; } |
| 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. |
| class
CWnd : public CCmdTarget { // sehr viele Member }; |
| class
CButton : public CWnd { //... // Constructors public: CButton(); BOOL Create(LPCTSTR lpszCaption, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID); // Attributes UINT GetState() const; void SetState(BOOL bHighlight); int GetCheck() const; void SetCheck(int nCheck); UINT GetButtonStyle() const; void SetButtonStyle(UINT nStyle, BOOL bRedraw = TRUE); #if (WINVER >= 0x400) HICON SetIcon(HICON hIcon); HICON GetIcon() const; HBITMAP SetBitmap(HBITMAP hBitmap); HBITMAP GetBitmap() const; HCURSOR SetCursor(HCURSOR hCursor); HCURSOR GetCursor(); #endif // Overridables (for owner draw only) virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); // Implementation virtual ~CButton(); protected: virtual BOOL OnChildNotify(UINT, WPARAM, LPARAM, LRESULT*); }; |
| //Testklasse xINT.h #pragma once #define _TEST_ //#include <windows.h> #include <conio.h> #include <iostream> /* void textcolor(WORD color) { SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), color); } const int farbe1 = 3; const int farbe2 = 15; */ class xINT { private: int num; static int countCtor; static int countDtor; static int countCopycon; static int countOpAssign; public: xINT() { #ifdef _TEST_ //textcolor(farbe1); std::cout << this << ": " << "ctor" << std::endl; //textcolor(farbe2); #endif ++countCtor; } ~xINT() { #ifdef _TEST_ //textcolor(farbe1); std::cout << this << ": " << "dtor" << std::endl; //textcolor(farbe2); #endif ++countDtor; } xINT(const xINT& x) { #ifdef _TEST_ //textcolor(farbe1); std::cout << this << ": " << "copycon von " << std::dec << &x << std::endl; //textcolor(farbe2); #endif num = x.getNum(); ++countCopycon; } xINT& operator=(const xINT& x) { if (&x == this) { #ifdef _TEST_ //textcolor(farbe1); std::cout << "Selbstzuweisung mit op=" << std::endl; //textcolor(farbe2); #endif } #ifdef _TEST_ //textcolor(farbe1); std::cout << this << ": " << "op= von " << std::dec << &x << std::endl; //textcolor(farbe2); #endif 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(); } |
| #include
"stdafx.h" #include "xINT.h" int _tmain() { { xINT i; wait(); } wait(); xINT::statistik(std::cout); wait(); return 0; } |
| #include
"stdafx.h" #include "xINT.h" int _tmain() { xINT *pi; { pi = new xINT; wait(); } wait(); delete pi; wait(); xINT::statistik(std::cout); wait(); return 0; } |
| #include
"stdafx.h" #include "xINT.h" int _tmain() { xINT *pi; { pi = new xINT[5]; wait(); } wait(); delete[] pi; wait(); xINT::statistik(std::cout); wait(); return 0; } |
| #include "stdafx.h" #include "xINT.h" 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 _tmain() { { A a; wait(); } wait(); xINT::statistik(std::cout); wait(); return 0; } |
| //... { A a[5]; wait(); } //... |
| Typ
in A |
Typ
in xINT |
Abstand
|
| double |
int |
16
(erwartet: 12 = 8+4) |
| float
oder int |
int |
8 (erwartet: 8 = 4+4) |
| int |
double |
16 (erwartet: 12 = 8+4) |
| double |
double |
16 (erwartet: 16 = 8+8) |
| #include
"stdafx.h" #include "xINT.h" 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 _tmain() { { A a[5]; wait(); } wait(); xINT::statistik(std::cout); wait(); return 0; } |
| //... private: double a; xINT i1; xINT i2; public: //... |
| #include "stdafx.h" #include "xINT.h" 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 _tmain() { { A a[5]; wait(); } wait(); xINT::statistik(std::cout); wait(); return 0; } |
| #include
"stdafx.h" #include "xINT.h" 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 _tmain() { { D d[3]; wait(); } wait(); xINT::statistik(std::cout); wait(); return 0; } |
| int _tmain() { { D d; std::cout << d.getNum() << std::endl; wait(); } wait(); xINT::statistik(std::cout); wait(); return 0; } |
| int _tmain() { { D d; std::cout << d.A::getNum() << std::endl; std::cout << d.B::getNum() << std::endl; wait(); } wait(); xINT::statistik(std::cout); wait(); return 0; } |
| #include "stdafx.h" #include "xINT.h" 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 _tmain() { { D d; 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(); return 0; } |
| #include
"stdafx.h" #include "xINT.h" using namespace std; 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(); { cout << "Klasse A:" << endl; A a(i); wait(); cout << "Klasse B:" << endl; B b(i); wait(); } wait(); return 0; } |
| #include
"stdafx.h" #include "xINT.h" #include <vector> #include <list> #include <deque> #include <algorithm> using namespace std; int _tmain() { 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 _tmain() { 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 "stdafx.h" #include "xINT.h" #include <vector> #include <list> #include <deque> #include <algorithm> using namespace std; int _tmain() { 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 _tmain() { 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) |
| #include "stdafx.h" #include "xINT.h" using namespace std; int _tmain(int argc, _TCHAR* argv[]) { { xINT i1, i2; i1.setNum(42); i2 = i1; cout << i1.getNum() << " " << i2.getNum() << endl; wait(); } wait(); } |
| #include "stdafx.h" #include "xINT.h" using namespace std; int _tmain() { { xINT i1; i1.setNum(42); i1 = i1; cout << i1.getNum() << 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 "stdafx.h" #include "xINT.h" #include <fstream> #include <vector> #include <algorithm> using namespace std; int _tmain() { { 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 "stdafx.h" #include "xINT.h" #include <fstream> #include <vector> #include <algorithm> using namespace std; int _tmain() { 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
"stdafx.h" #include "xINT.h" #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 _tmain() { 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
"stdafx.h" #include "xINT.h" #include <stack> int _tmain() { { 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 "stdafx.h" #include "xINT.h" #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 _tmain() { { 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
"stdafx.h" #include "xINT.h" #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 _tmain() { { 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 _tmain() { { Stack<xINT,vector<xINT>> stack; xINT x; //... |
| int
_tmain() { 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 _tmain() { 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 "stdafx.h" #include "xINT.h" #include <memory> //auto_ptr int _tmain() { { 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 "stdafx.h" #include "xINT.h" #include <memory> int _tmain() { { xINT* p1(new xINT[3]); delete[] p1; } wait(); { std::auto_ptr<xINT> p2(new xINT[3]); //falsch!!! } wait(); return 0; } |
| #include "stdafx.h" #include "xINT.h" #include <memory> using namespace std; int _tmain() { { 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 "stdafx.h" #include <vector> using namespace std; int _tmain() { vector<int>v(1000000000); //10^9 Elemente wait(); return 0; } |
| #include
"stdafx.h" #include <vector> using namespace std; int _tmain() { try { vector<int>v(1000000000); } catch(...) { cout << "Fehler" << endl; } wait(); return 0; } |
| #include "stdafx.h" #include <vector> using namespace std; class std::exception; int _tmain() { 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
"stdafx.h" #include <vector> #include <exception> using namespace std; int _tmain() { try { vector<int>v(1000000000); } catch(exception& e) { cout << typeid(e).name( ) << endl; cout << e.what() << endl; } wait(); return 0; } |
| #include
"stdafx.h" #include <vector> #include <exception> using namespace std; int _tmain() { 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
"stdafx.h" #include <exception> using namespace std; int _tmain() { 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 "stdafx.h" #include <string> using namespace std; int _tmain() { 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 "stdafx.h" #include <vector> class exception; using namespace std; int _tmain() { 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
"stdafx.h" #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 _tmain() { 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 _tmain() { // wie oben } |
| //wie
oben void function() throw () //kein Fehlertyp darf geworfen werden { //wie oben } int _tmain() { // wie oben } |

| #include "stdafx.h" #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]; } return 0; } |
| #include "stdafx.h" #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]; } return 0; } |
|
//
MySingleton.h
class MySingleton |
// MySingleton.h class MySingleton : public Singleton<Klasse_fuer_vereinzelte_Objekte> |