Zum Inhalt springen

orsino

Mitglieder
  • Gesamte Inhalte

    33
  • Benutzer seit

  • Letzter Besuch

Alle Inhalte von orsino

  1. Ich hab zwar die Prüfung hinter mir, möchte aber trotzdem mal einen Blick auf die Bewertung werfen, wo Punkte abgezogen wurden und so. Wie bekommt man diese Möglichkeit?
  2. Jeff Prosise beschreibt in 'Programming Windows with MFC' eine Möglichkeit This problem is easily solved with a message pump. Here's the proper way to execute a lengthy procedure in a single-threaded MFC program: void CMainWindow::OnStartDrawing () { m_bQuit = FALSE; for (int i=0; i<NUMELLIPSES && !m_bQuit; i++) { DrawRandomEllipse (); if (!PeekAndPump ()) // PeekAndPump entspricht DoEvents break; } } void CMainWindow::OnStopDrawing () { m_bQuit = TRUE; } BOOL CMainWindow::PeekAndPump () { MSG msg; while (::PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE)) { if (!AfxGetApp ()->PumpMessage ()) { ::PostQuitMessage (0); return FALSE; } } LONG lIdle = 0; while (AfxGetApp ()->OnIdle (lIdle++)); return TRUE; } PeekAndPump enacts a message loop within a message loop. Called at the conclusion of each iteration through OnStartDrawing's for loop, PeekAndPump first calls CWinThread::PumpMessage to retrieve and dispatch messages if ::PeekMessage indicates that messages are waiting in the queue. A 0 return from PumpMessage indicates that the last message retrieved and dispatched was a WM_QUIT message, which calls for special handling because the application won't terminate unless the WM_QUIT message is retrieved by the main message loop. That's why PeekAndPump posts another WM_QUIT message to the queue if PumpMessage returns 0, and why the for loop in OnStartDrawing falls through if PeekAndPump returns 0. If a WM_QUIT message doesn't prompt an early exit, PeekAndPump simulates the framework's idle mechanism by calling the application object's OnIdle function before returning. funktioniert prinzipiell, habe es auch schon mal verwendet, kann aber je nach verwendung etwas umständlich werden. ich weiß nicht, ob sich dein problem so lösen lässt. vielleicht solltest du über einen worker thread nachdenken.
  3. orsino

    Methoden in C++

    Also das mit den konstruktoren musst du dir wohl nochmal ansehen, Crush. class bing { public: bing(int x=0):zahl(0){} virtual ~bing(){}; virtual void set(const int x){zahl=x;} virtual int get() const {return zahl;} private: int zahl; }; class ding : virtual bing { public: ding(){bing::bing();}; // basis konstruktor wird zweimal aufgerufen virtual ~ding(){bing::~bing();}; // subobject vom typ bing wird zweimal zerstört void set(const int x){bing::set(x);} void setown(const int x) {zahl=x;} int get() const {return bing::get();} int getown() const {return zahl;} private: int zahl; }; ich hab mal die zwei klassen als beispiel genommen. wozu wird im ctor von ding der basis-ctor expilzit aufgerufen? wenn das programm die öffnende geschweifte Klammer des ctors von ding erreicht ist das komplette ding - objekt schon konstruiert und der basis ctor wurde bereits aufgerufen. der compiler generiert standardmäßig einen aufruf des default ctors der Basisklasse. wenn man das nicht möchte oder es nicht geht, muss man den aufruf selbst explizit in der initialisierungsliste VOR der geschweiften klammer angeben ding() : bing("ding ruft bing") {} // unter der annahme bing hat einen ctor bing(char* Msg); im vorliegenden fall ding(){bing::bing();}; wird innerhalb das anweisungsblocks ein namenloses objekt vom typ bing erzeugt, das beim verlassen des blocks sofort wieder zerstört wird (im debugger kann man den destruktor aufruf von bing verfolgen). ähnlich ist es beim destruktor. NACHDEM ~ding() fertig ist wird automatisch ~bing() aufgerufen. der explizite aufruf innerhalb von ~ding() ist etwa so, als wollte man den keller vor dem dach abreißen. der folgende code würde zum beispiel abstürzen class bing { public: bing(int x=0):zahl(0){pFoo = new int(10);} virtual ~bing(){delete pFoo;} private: int zahl; int *pFoo; }; class ding : virtual bing { public: ding(){bing::bing();}; virtual ~ding(){bing::~bing();}; // zweimal delete pFoo private: int zahl; }; man könnte das problem umgehen virtual ~bing(){if (pFoo) {delete pFoo; pFoo = NULL;};} aber die eigentliche logik ist nicht korrekt. richtiger wäre ding so zu definieren class ding : virtual bing { public: ding(){} virtual ~ding(){} private: int zahl; }; und noch was zum goto. ich selbst hab mein letztes goto vor vielen jahren (damals noch in basic) verwendet. aber es gibt durchaus sinnvolle verwendungen, wie ich erst jetzt wieder in Tom Archers 'Inside C#' gelesen habe (ja c# hat ein goto). er beschreibt, dass der goto befehl in ungnade fiel mit der veröffentlichung des artikels 'Go To Statement Considered Harmful' (Edsger W. Dijkstra, 1968) http://www.acm.org/classics/oct95/ in einem switch block zum beispiel könnte es sinnvoll sein ein goto zu verwenden.
  4. orsino

    Fragen zu Unicode

    Das Makro _UNICODE wird nur für die Header-Dateien der C-Laufzeitbibliothek verwendet, das Makro UNICODE dagegen für die Win32-Header-Dateien. Normalerweise müssen beide Makros definiert sein. Ich mache das immer in Projekt-Settings bei den Präprozessor-Einstellungen. In der MSDN habe ich folgendes gefunden: To compile code for Unicode, you need to #define UNICODE for the Win32 header files and #define _UNICODE for the C Run-time header files. These #defines must appear before the following: #include <windows.h> and any included C Run-time headers. The leading underscore indicates deviance from the ANSI C standard. Because the Windows header files are not part of this standard, it is allowable to use UNICODE without the leading underscore.
  5. Ich hab das ganze auch mal ausprobiert und festgestellt das mit den Pointer-Addressen alles stimmt. Wenn man sich den Assembler Code (ich benutze Visual C++6 als Compiler) dazu ansieht, dann ist es eigentlich ganz leicht zu erklären. Bei der Zuweisung: int nErgebnis = nConstWert + 50; schreibt der Compiler int nErgebnis = 150; das heißt der Wert steht schon zu Beginn fest im Code. Der Compiler sieht das nConstWert als konstanter Integer 100 definiert ist und ersetzt deshalb jedes Vorkommen mit dem konkreten Wert. Jede Manipulation der Variablen während des Programms bleibt also unberücksichtigt. Dieses Verhalten ist compilerabhängig und in den Standards nicht definiert. Nach der Zeile * pAufConstWert = 50; ist jeder Ausdruck der nConstWert benutzt nicht definiert. Ich habe auf Google einige Posts zu diesem Thema gefunden und bei einigen Compilern würde 100 und bei anderen 150 herauskommen. Um wirklich den aktuellen Wert aus dem Speicher zu lesen müsste man in dem Fall: int nErgebnis = *const_cast<int*>(&nConstWert) + 50; schreiben.
  6. vielleicht ist das ja auch interessant //: C11:PmemFunDefinition.cpp class Simple2 { public: int f(float) const { return 1; } }; int (Simple2::*fp)(float) const; int (Simple2::*fp2)(float) const = &Simple2::f; int main() { fp = &Simple2::f; } ///:~ In the definition for fp2 you can see that a pointer to member function can also be initialized when it is created, or at any other time. Unlike non-member functions, the & is not optional when taking the address of a member function. However, you can give the function identifier without an argument list, because overload resolution can be determined by the type of the pointer to member. weiteres Beispiel: //: C11:PointerToMemberFunction2.cpp #include <iostream> using namespace std; class Widget { void f(int) const { cout << "Widget::f()\n"; } void g(int) const { cout << "Widget::g()\n"; } void h(int) const { cout << "Widget::h()\n"; } void i(int) const { cout << "Widget::i()\n"; } enum { cnt = 4 }; void (Widget::*fptr[cnt])(int) const; public: Widget() { fptr[0] = &Widget::f; // Full spec required fptr[1] = &Widget::g; fptr[2] = &Widget::h; fptr[3] = &Widget::i; } void select(int i, int j) { if(i < 0 || i >= cnt) return; (this->*fptr)(j); } int count() { return cnt; } }; int main() { Widget w; for(int i = 0; i < w.count(); i++) w.select(i, 47); } ///:~ Similarly, when the pointer-to-member is dereferenced, it seems like (this->*fptr)(j); is also over-specified; this looks redundant. Again, the syntax requires that a pointer-to-member always be bound to an object when it is dereferenced. die Beispiele sind aus dem Buch Thinking in C++ von Bruce Eckel. Kann man sich als pdf bei http://www.bruceeckel.com laden.
  7. orsino

    Vector in OOP

    In dem Fall würde ich es in die Header Datei schreiben, zumindest die Typdefinition. //KUNDE.H #include <vector> using namespace std ; /* den vector include würde ich in das standard include stdafx.h ziehen */ #ifndef KUNDE_H #define KUNDE_H class Anlage; // Vorwärtsdeklaration typedef vector<Anlage*> ANLVECTOR; /* Muss nach der vorwärtsdeklaration von class Anlage stehen deshalb kann es auch nicht im Kunde.cpp vor dem dem Kunde.h include stehen. Und wenn es danach stehen würde, kannst du ANLVECTOR logischerweise nicht im header verwenden. Außerdem enthält der ANLVECTOR bei mir nur pointer auf anlage-objekte - macht operationen mit dem vector schneller. Wenn du wirklich komplette objekte in dem vector ablegen willst, reicht die einfache vorwärtsdeklaration nicht aus (geht nur für pointer). In diesem fall musst du vorher Anlage.h inkludieren. */ class Kunde { public: Kunde(char* n); ~Kunde(){}; ... private: char* seinName; Anlage* seineAnlage; //bisher nur eine Anlage, mit dem Vector werden's viele! ... }; #endif
  8. so gehts ShellExecute(NULL, "open", "cmd", "/k dir c:", NULL, SW_SHOWNORMAL );

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...