2009-08-01 14 views
16

Dies kann eine kurze & einfache Frage, aber ich habe nie eine befriedigende Antwort darauf:C++ main() in einem großen OOP Projekt

Welchen Code ist die Funktion main() in der Regel in einem bestehen aus großes C++ Projekt? Wäre es eine falsche Annahme zu denken, dass es normalerweise nur ein (umhüllendes) Klassenobjekt initialisiert und eine Funktion darin aufruft, Dinge abzustellen?

Warum ist main() nicht eine Methode an erster Stelle? Ist es rückwärtskompatibel mit C?

+1

Der Grund, dass es keine Member-Funktion ist, dass Sie dann eine Möglichkeit benötigen, um anzugeben, zu welcher Klasse es eine Member-Funktion von ist. C++ hat nichts wie das Manifest von Java und keine Reflektion. –

+0

von einer konzeptionellen Ebene benötigt jedes Programm einen Einstiegspunkt, im Falle von "klassischem" C++ ist dies innerhalb der ausführbaren Datei, die der Compiler erzeugt, wenn das Programm startet, gibt es keine Klasse, für die main eine Methode sein könnte. In interpretierten Sprachen wird die Runtime zuerst ausgeführt und richtet einen Kontext ein, in dem die Anwendung ausgeführt wird, bevor sie gestartet wird, sodass der Einstiegspunkt eine Methode/Mitglied einer zuvor eingerichteten Klasse ist, falls die Sprache/Laufzeit dies erlaubt/wünscht. – Mark

+2

@Mark: was? Der Compiler ist dafür verantwortlich, Code zu senden, um verschiedene Dinge einschließlich statischer Member von Klassen vor der Ausführung von main() zu initialisieren. Insofern Klassen in C++ zur Laufzeit überhaupt existieren können, gibt es viele Klassen, bevor der Einstiegspunkt aufgerufen wird. Es könnte sogar viele Objekte geben. –

Antwort

10

In meinem Code ist es im Grunde ein Konstruktor Aufruf, möglicherweise ein Methodenaufruf, und einige Ausnahme Behandlung. Dies ist die wichtigste für eigene meine Projekte (Header und Kommentare weggelassen, und die Formatierung von SO, wie üblich verkorksten):

int main(int argc, char * argv[]) { 
    int result = 0; 
    try { 
     CLIHandler ch(argc, argv); 
     result = ch.ExecCommand(); 
    } 
    catch(const Exception & ex) { 
     result = ExceptionHandler::HandleMyError(ex); 
    } 
    catch(const std::exception & ex) { 
     result = ExceptionHandler::HandleOtherError(ex); 
    } 
    catch(...) { 
     result = ExceptionHandler::HandleUnknownError(); 
    } 
    return result; 
} 
+0

Warum ersetzen Sie nicht einfach alle Ihre 'result =' durch 'return'? – GManNickG

+2

Mund aus! Haben Sie noch nie von der Anforderung gehört, dass in einem gut strukturierten Code eine Funktion nur einen Exit-Punkt haben muss? Aber um es ernst zu meinen, ist mein Weg einfacher zu debuggen, da Sie eine Variable zu inspizieren haben. –

+0

Ah, ich sehe lol. Du hast mir Angst gemacht. Ich war wie "FUUU- was ?!". Ich glaube, ich musste die Rückgabevariable nie überprüfen, mein Fehlerhandler druckt es zusammen mit der Ausnahme aus. Ansonsten ist unser Code der gleiche. – GManNickG

1

Die kurze Antwort: es kommt darauf an. Es kann durchaus einige lokale Objekte erzeugen, die für die Dauer des Programms benötigt werden, sie konfigurieren, sie über einander erzählen und eine lange laufende Methode auf einem von ihnen aufrufen.

Ein Programm benötigt einen Einstiegspunkt. Wenn main eine Methode für ein Objekt sein müsste, welcher Klassentyp sollte es sein?

Mit main als globaler Einstiegspunkt kann es wählen, was eingerichtet wird.

2

-Mine zu tun in der Regel

  • Befehlszeilen
  • Initialisierung von Top-Level-Parsing-Objekte
  • Exception Handling
  • main 'exec' Schleife Eingabe

Wie ich es verstehe int main(int argc, char *argv[]) ist im Wesentlichen eine Konvention aufgrund der C Erbe. Mir kam es nie sonderbar vor, aber eher nützlich. C++ erweitert C schließlich ... (und ja, es gibt feine Unterschiede, aber das war nicht die Frage hier).

2

Ja, der Grund ist Abwärtskompatibilität. main ist der einzige Einstiegspunkt, der in einem C-Programm zulässig ist, das ausführbare Dateien und damit in einem C++ - Programm erzeugt.

Wie für was in einem C++ Haupt zu tun, hängt es ab. In der Regel verwendet, um I:

  • globale Initialisierung (zB des Logging-Subsystem)
  • Parse-Befehlszeile Argumente auszuführen und eine richtige Klasse definieren sie
  • ein Anwendungsobjekt zuzuweisen, das Setzen es mit bis usw.
  • führen Sie das Anwendungsobjekt (in meinem Fall eine Endlosschleife Methode. GUI-Programmierung)
  • Finalisierung durchführen, nachdem das Objekt seine Aufgabe abgeschlossen hat.

oh und ich vergaß den wichtigsten Teil einer Anwendung

  • zeigen die Begrüßungsbildschirm
0

Sie eine statische Klasse Member-Funktion anstelle der Haupt mit dem MSVC++ Compiler, indem Sie verwenden können der Einstiegspunkt in den Projekteinstellungen unter den erweiterten Linkeroptionen.

Es hängt wirklich von Ihrem Projekt ab, was Sie dort platzieren möchten ... wenn es klein ist, können Sie auch Meldungsschleifen, Initialisierungs- und Shutdown-Code dort einfügen. In größeren Projekten müssen Sie diese in ihre eigenen Klassen/Funktionen verschieben oder eine monolithische Einstiegspunktfunktion haben.

0

Nicht alle C++ - Anwendungen sind OOP und jeder Code erfordert einen Einstiegspunkt.

Wenn ich OOP-Code schreibe, neigt meine main() dazu, eine Objekt Instanziierung, vielleicht durch einige Benutzereingaben durchgeführt. Ich tue es so, weil ich das Gefühl habe, dass die 'Arbeit' in einem Objekt ausgeführt werden soll, ansonsten ist der Code nicht im 'Geist' von OOP geschrieben.

0

Wirklich große Projekte umfassen nicht nur ein einzelnes Programm. Daher wird es mehrere ausführbare Dateien geben, die jeweils ihre eigene Hauptdatei haben. Nebenbei ist es üblich, dass diese ausführbaren Dateien asynchron über Warteschlangen kommunizieren.

Ja, jedes Haupt neigt dazu, sehr klein zu sein, ein Rahmenwerk oder was auch immer initialisierend.

Meinst du warum ist main() eine Funktion und nicht eine Methode der Klasse? Nun, für welche Klasse wäre es eine Methode? Ich denke, es ist hauptsächlich C++ 's Erbe von C, aber ... alles muss irgendwo anfangen :-)

+1

Haupt ist eine Funktion, keine Methode ... – micmoo

+0

Danke, ja du hast Recht. – djna

0

ich in die Regel Haupt verwendet für in der Kommandozeile zu lesen, globale Variablen zu initialisieren, und dann Aufruf der entsprechenden Funktionen/Methoden.

1

Meine main() - Funktion erstellt oft verschiedene Objekte auf oberster Ebene und gibt ihnen Referenzen. Dies hilft, die Kopplung zu minimieren und die genauen Beziehungen zwischen den verschiedenen Top-Level-Objekten, die auf das Hauptobjekt beschränkt sind, beizubehalten.

Oft haben diese Top-Level-Objekte unterschiedliche Lebenszyklen mit den Methoden init(), stop() und start(). Die main() -Funktion verwaltet die Objekte in den gewünschten Ausführungszustand, wartet auf alles, was anzeigt, dass es Zeit zum Herunterfahren ist, und schaltet dann alles auf eine kontrollierte Weise ab. Auch dies trägt dazu bei, dass die Dinge ordnungsgemäß entkoppelt sind, und behält das Management des Lebenszyklus der obersten Ebene an einem leicht verständlichen Ort bei. Ich sehe dieses Muster in reaktiven Systemen, besonders in solchen mit vielen Fäden.