2009-08-01 12 views
16

Questo può essere un breve & semplice domanda, ma non ho mai trovato una risposta soddisfacente ad esso:C++ main() in una grande OOP progetto

Cosa codice non la funzione main() di solito sono costituiti da un grande progetto C++? Sarebbe un'ipotesi errata pensare che di solito è solo inizializzare un oggetto di classe (wrapping) e chiamare una funzione al suo interno per risolvere il problema?

Perché main() non è un metodo in primo luogo? È per preservare la retrocompatibilità con C?

+1

Il motivo per cui non è una funzione membro è che quindi è necessario un modo per specificare di quale classe è una funzione membro. C++ non ha nulla di simile a manifest di Java e nessuna riflessione. –

+0

da un livello più concettuale, ogni programma ha bisogno di un punto di ingresso, nel caso di C++ "classico" questo è all'interno dell'eseguibile che il compilatore produce, quando il programma inizia non c'è classe nell'esistenza che il main possa essere un metodo di. Nei linguaggi interpretati, il runtime viene eseguito per primo e imposta un contesto per l'esecuzione dell'applicazione prima che inizi, in modo che il punto di ingresso sia un metodo/membro di una classe di impostazione precedentemente possibile se la lingua/runtime lo consente/lo desidera. – Mark

+2

@ Mark: cosa? Il compilatore è responsabile dell'emissione del codice per inizializzare varie cose, inclusi i membri statici delle classi, prima che main() venga eseguito. Nella misura in cui si può affermare che le classi esistono in runtime in C++, esistono molte classi esistenti prima che venga chiamato il punto di ingresso. Potrebbero esserci anche molti oggetti in esistenza. –

risposta

10

Nel mio codice, è fondamentalmente una chiamata costruttore, forse una chiamata di metodo, e un po' la gestione delle eccezioni. Questo è il principale per proprio dei miei progetti (intestazioni e commenti omessi, e la formattazione incasinato da SO, come al solito):

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

Perché non sostituire semplicemente tutti i tuoi 'result =' con 'return'? – GManNickG

+2

Lavati la bocca! Non hai mai sentito dire che in tutti i codici ben strutturati una funzione deve avere un solo punto di uscita ???? Ma per essere seri, la mia strada è più facile da eseguire il debug, poiché hai una variabile da ispezionare. –

+0

Ah, vedo lol. Mi hai spaventato. Ero come, "FUUU- cosa ?!". Immagino di non aver mai dovuto ispezionare la variabile return, il mio gestore degli errori lo stampa insieme all'eccezione. Altrimenti il ​​nostro codice è lo stesso. – GManNickG

1

La risposta breve: dipende. Può benissimo creare alcuni oggetti locali che sono necessari per la durata del programma, configurarli, dirgli l'uno dell'altro e chiamare un metodo a lunga esecuzione su uno di essi.

Un programma richiede un punto di ingresso. Se main doveva essere un metodo su un oggetto, quale tipo di classe dovrebbe essere?

Con main come punto di ingresso globale è possibile scegliere cosa impostare.

2

miniera solito do

  • riga di comando parsing
  • inizializzazione di primo livello oggetti
  • gestione delle eccezioni
  • entrando principale anello 'exec'

quanto mi risulta , int main(int argc, char *argv[]) è essenzialmente una convenzione a causa del patrimonio C. Non mi è mai sembrato strano, ma piuttosto utile. C++ estende C dopo tutto ... (e sì c'è una bella differenza ma quella non era la domanda qui).

2

Sì, il motivo è la compatibilità con le versioni precedenti. main è l'unico punto di ingresso consentito in un programma C che produce eseguibili e quindi in un programma C++.

Per quanto riguarda cosa fare in un C++ principale, dipende. In generale, ho usato per:

  • eseguire inizializzazione globale (ad esempio del sottosistema di registrazione)
  • argomenti della riga comandi analizzare e definire una classe propria che li contiene
  • allocare un oggetto applicazione, la sua creazione etc.
  • eseguire l'oggetto applicazione (nel mio caso, un metodo di ciclo infinito. Programmazione GUI)
  • finalizzazione dopo che l'oggetto ha completato il proprio compito.

oh e ho dimenticato la parte più importante di una domanda di

  • mostrano la splashscreen
0

È possibile utilizzare una funzione di membro di classe statico al posto del principale con il compilatore MSVC++ scegliendo il punto di ingresso nelle impostazioni del progetto, sotto le opzioni avanzate del linker.

Dipende molto dal tuo progetto in merito a ciò che vuoi inserire ... se è piccolo, puoi anche inserire loop di messaggi, codice di inizializzazione e di spegnimento. Nei progetti più grandi dovrai spostarli nelle loro classi/funzioni o meno avere una funzione di punto di ingresso monolitico.

0

Non tutte le applicazioni C++ sono OOP e in entrambi i casi tutto il codice richiede un punto di ingresso da cui iniziare.

Quando sto scrivendo il codice OOP, il mio main() tende a includere un'istanza di un oggetto, forse preceduta da qualche input dell'utente. Lo faccio in questo modo perché ritengo che il "lavoro" debba essere fatto all'interno di un oggetto, altrimenti il ​​codice non è scritto nello "spirito" di OOP.

0

I progetti di grandi dimensioni non comprendono solo un singolo programma. Quindi ci saranno diversi eseguibili ciascuno con il proprio main. Di passaggio, è abbastanza comune che questi eseguibili comunichino in modo asincrono tramite le code.

Sì, ogni main tende ad essere molto piccolo, inizializzando un framework o qualsiasi altra cosa.

Intendi perché main() è una funzione piuttosto che un metodo di classe? Bene, quale classe sarebbe un metodo di? Penso che sia in gran parte del patrimonio da C++ C s ', ma ... tutto devo iniziare da qualche parte :-)

+1

main è una funzione, non un metodo ... – micmoo

+0

Grazie, sì hai ragione. – djna

0

Io di solito uso principale per la lettura nella riga di comando, l'inizializzazione delle variabili globali, e quindi chiamando le funzioni/i metodi appropriati.

1

La mia funzione main() spesso costruisce vari oggetti di livello superiore, fornendo loro riferimenti l'uno con l'altro. Ciò consente di ridurre al minimo l'accoppiamento, mantenendo le relazioni esatte tra i diversi oggetti di livello superiore confinati al principale.

Spesso questi oggetti di livello superiore hanno cicli di vita distinti, con i metodi init(), stop() e start(). La funzione main() gestisce il recupero degli oggetti nello stato di esecuzione desiderato, attende qualsiasi cosa indichi che è il momento di spegnersi e quindi chiude tutto in modo controllato. Ancora una volta, questo aiuta a mantenere le cose correttamente disaccoppiate e mantiene la gestione del ciclo di vita di primo livello in un posto facilmente comprensibile. Vedo questo schema molto nei sistemi reattivi, specialmente quelli con molti fili.