2009-08-01 9 views
16

Cela peut être une courte question simple & ++, mais je ne l'ai jamais trouvé une réponse satisfaisante à elle:C principal() dans un grand projet POO

Quel code ne la fonction principale() consistent généralement en un grand projet C++? Serait-ce une supposition incorrecte de penser qu'il suffit généralement d'initialiser un objet de classe (wrapping) et d'appeler une fonction à l'intérieur de celui-ci pour déclencher les choses?

Pourquoi main() n'est-elle pas une méthode en premier lieu? Est-ce pour préserver la rétrocompatibilité avec C?

+1

La raison pour laquelle ce n'est pas une fonction membre est que vous auriez besoin d'un moyen de spécifier de quelle classe il s'agit. C++ n'a rien à voir avec le manifeste de Java et aucune réflexion. –

+0

d'un niveau plus conceptuel, chaque programme a besoin d'un point d'entrée, dans le cas de C++ "classique" c'est dans l'exécutable que le compilateur produit, quand le programme démarre il n'y a pas de classe. Dans les langages interprétés, le runtime s'exécute d'abord et configure un contexte pour que l'application s'exécute avant que le point d'entrée soit une méthode/membre d'une classe précédemment configurée si le langage/runtime le permet/le désire. – Mark

+2

@Mark: quoi? Le compilateur est responsable de l'émission de code pour initialiser diverses choses, y compris les membres statiques des classes, avant l'exécution de main(). Dans la mesure où l'on peut dire que les classes existent à l'exécution en C++, il existe de nombreuses classes avant l'appel du point d'entrée. Il pourrait même y avoir beaucoup d'objets dans l'existence aussi. –

Répondre

10

Dans mon code, il s'agit essentiellement d'un appel de constructeur, éventuellement d'un appel de méthode, et d'une gestion des exceptions. Tel est le principal propre de mes projets (en-têtes et commentaires omis, et le formatage foiré par SO, comme d'habitude):

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

Pourquoi ne pas simplement remplacer tous vos 'result =' avec 'return'? – GManNickG

+2

Lavez-vous la bouche! N'avez-vous jamais entendu parler de l'exigence selon laquelle, dans tout code bien structuré, une fonction doit avoir un seul point de sortie? Mais pour être sérieux, mon chemin est plus facile à déboguer, car vous avez une variable à inspecter. –

+0

Ah, je vois lol. Tu m'as fait peur. J'étais comme, "FUUU- quoi?!". Je suppose que je n'ai jamais eu à inspecter la variable de retour, mon gestionnaire d'erreur l'imprime avec l'exception. Sinon, notre code est le même. – GManNickG

1

La réponse courte: cela dépend. Il peut très bien créer quelques objets locaux nécessaires pour la durée du programme, les configurer, les informer les uns des autres et appeler une méthode longue sur l'un d'entre eux.

Un programme a besoin d'un point d'entrée. Si main devait être une méthode sur un objet, quel type de classe devrait-il être?

Avec main comme point d'entrée global, il peut choisir ce qu'il doit configurer.

2

le mien habituellement

  • commande d'analyse syntaxique en ligne
  • Initialisation des objets de haut niveau
  • Gestion des exceptions
  • entrant dans la boucle principale 'exec'

Si je comprends bien , int main(int argc, char *argv[]) est essentiellement une convention en raison de l'héritage C. Je ne me suis jamais trouvé étrange, mais plutôt utile. C++ étend C après tout ... (et oui il y a une belle différence mais ce n'était pas la question ici).

2

Oui, la raison en est la rétrocompatibilité. main est le seul point d'entrée autorisé dans un programme C produisant des exécutables, et donc dans un programme C++. Quant à ce qu'il faut faire dans une main C++, cela dépend de. En général, je faisais:

  • effectuer l'initialisation globale (par exemple du sous-système de journalisation)
  • analyse syntaxique des arguments de ligne de commande et de définir une classe appropriée les contenant
  • allouer un objet d'application, sa mise en place, etc.
  • Exécuter l'objet d'application (dans mon cas, une méthode de boucle infinie Programmation GUI)
  • finalisation après que l'objet a terminé sa tâche.

oh et j'ai oublié la partie la plus importante d'une application

  • montrent la splashscreen
0

Vous pouvez utiliser une fonction de membre de classe statique à la place principale avec le MSVC++ compilateur en choisissant le point d'entrée dans les paramètres du projet, sous les options avancées de l'éditeur de liens.

Cela dépend vraiment de votre projet quant à ce que vous voulez placer là-bas ... si elle est petite, vous pouvez aussi mettre des boucles de messages, l'initialisation et le code d'arrêt là-dedans. Dans les projets plus importants, vous devrez les déplacer dans leurs propres classes/fonctions ou moins avoir une fonction de point d'entrée monolithique.

0

Toutes les applications C++ ne sont pas des OOP et, dans les deux cas, tout le code nécessite un point d'entrée. Lorsque j'écris du code POO, mon main() tend à inclure une instanciation d'objet, peut-être procédée par une entrée de l'utilisateur. Je le fais de cette façon parce que je sens que le 'travail' est censé être fait dans un objet, sinon le code n'est pas écrit dans 'l'esprit' de la POO.

0

Les projets vraiment importants ne comprennent généralement pas un seul programme. Par conséquent, il y aura plusieurs exécutables chacun avec leur propre main. En passant, il est assez fréquent que ces exécutables communiquent de manière asynchrone via des files d'attente.

Oui, chaque principale a tendance à être très petite, en initialisant un cadre ou quoi que ce soit.

Voulez-vous dire pourquoi main() est une fonction plutôt qu'une méthode de classe? Eh bien, de quelle classe serait-elle une méthode? Je pense que c'est surtout l'héritage C++ de C, mais ... tout doit commencer quelque part :-)

+1

principal est une fonction, pas une méthode ... – micmoo

+0

Merci, oui vous avez raison. – djna

0

J'utilise habituellement principale pour la lecture dans la ligne de commande, l'initialisation des variables globales, puis appeler les fonctions/méthodes appropriées.

1

Ma fonction main() construit souvent divers objets de niveau supérieur, en leur donnant des références les uns aux autres. Cela permet de minimiser le couplage, en conservant les relations exactes entre les différents objets de premier niveau confinés au principal.

Souvent, ces objets de niveau supérieur ont des cycles de vie distincts, avec les méthodes init(), stop() et start(). La fonction main() gère l'obtention des objets dans l'état de fonctionnement souhaité, attend tout ce qui indique qu'il est temps de s'arrêter, puis tout fermer de manière contrôlée. Encore une fois, cela aide à garder les choses bien découplées, et maintient la gestion du cycle de vie de haut niveau dans un endroit facilement compris. Je vois beaucoup de choses dans les systèmes réactifs, en particulier ceux avec beaucoup de threads.

Questions connexes