IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

découpage en fonction


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juin 2017
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2017
    Messages : 19
    Par défaut découpage en fonction
    Bonjour,
    Je suis débutant en C++ et j'essaye de découper mon programme en fonctions.
    Avant que je le découpe il fonctionnait, après il ne fonctionne plus.

    la structure de mon programme
    1)avant:
    Dans le main.cpp:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    bool init(); // Appel de la fonction
    bool init() // La fonction
    {}
    int main (int argc, char*args[]) // fonction main
    2) après:
    Dans le main.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #include init.h
     
    bool init();
    int main (int argc, char*args[])
    Dans le init.cpp:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #include init.h
     
    bool init() // la fonction
    {}
    Dans le init.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bool init(); // déclaration de la fonction
    Voyez vous déjà une erreur dans ma démarche?
    merci!

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    La démarche est correcte (mais il lever le bool init();qui serait resté dans main.cpp)

    Après quand tu dis, "après il ne fonctionne plus" est-ce ça ne compile plus ou est-ce que le code ne fait plus la même chose?
    Tu peux aussi mettre le texte exact de tes 4 fichiers en utilisant la balise bouton [#] car il y pas assez de données visibles ici pour t'aider.

  3. #3
    Membre éclairé Avatar de onilink_
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    611
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 611
    Par défaut
    Il faut bien comprendre la nuance entre déclaration du prototype de la fonction et implémentation de la fonction.

    Un programme C++ est séparé en modules (.cpp) et headers.
    Chaque module contiens ses implémentations de fonctions, et peut être compilé en parallèle à d'autres modules.
    Mais pour qu'un module connaisse les fonctions "publiques" des autres modules, il fait les déclarer dans des headers.
    Sans cela le compilateur ne peut pas savoir si une fonction utilisée par un module, et implémentée dans un autre module existe ou non.
    Sans prototype il va juste donner une erreur du genre "fonction non existante".

    En revanche, il est aussi tout a fait possible de déclarer un prototype de fonction, et appeler cette fonction, sans qu'elle n'existe dans aucun module.
    La compilation de chaque module se fera d'ailleurs sans problème, mais c'est lors de la phase de construction de l’exécutable que le linker va donner une erreur de la forme:
    "undefined reference of XXX"

    En bref:
    -"undefined reference of" => la fonction a un prototype de déclaré, mais n'a pas d'implémentation, il faut implémenter celle ci dans un module (.cpp)
    -"XXX was not declared" => la fonction n'a pas de prototype ou implémentation déclarée dans le module, il faut déclarer le prototype de la fonction dans un header et l'include au module
    -"multiple definition of" => la fonction a été implémentée plusieurs fois, le linker ne sait donc pas laquelle linker. Il faut utiliser le mot clé static (en C) ou un namespace anonyme (c++) pour qu'une fonction soit locale a un module (et donc privée)

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Humm... Tu as presque tout bon, sauf pour la dernière ligne:
    -"multiple definition of" => la fonction a été implémentée plusieurs fois, le linker ne sait donc pas laquelle linker. Il faut utiliser le mot clé static (en C) ou un namespace anonyme (c++) pour qu'une fonction soit locale a un module (et donc privée)
    La meilleure solution est -- toujours -- de veiller à ce qu'il n'y ait qu'une seule et unique implémentation de la fonction. Cela signifie donc qu'il faut ... supprimer l'implémentation qui correspond le moins bien aux besoins recherchés par la fonction

    Après, il reste le cas de fonctions que l'on doit -- pour une raison ou une autre -- implémenter dans le fichier d'en-tête (*.h ou *.hpp) et non dans un fichier d'implémémentation (*.cpp).

    Pour éviter le problème, on les déclarera inline
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Dans ton premier code, ton "appel à la fonction" est une erreur: ceci est la déclaration du prototype de la fonction.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #6
    Membre éclairé Avatar de onilink_
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    611
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 611
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Humm... Tu as presque tout bon, sauf pour la dernière ligne:

    La meilleure solution est -- toujours -- de veiller à ce qu'il n'y ait qu'une seule et unique implémentation de la fonction. Cela signifie donc qu'il faut ... supprimer l'implémentation qui correspond le moins bien aux besoins recherchés par la fonction

    Après, il reste le cas de fonctions que l'on doit -- pour une raison ou une autre -- implémenter dans le fichier d'en-tête (*.h ou *.hpp) et non dans un fichier d'implémémentation (*.cpp).

    Pour éviter le problème, on les déclarera inline
    En effet, mais je parlais plus du cas général du "gros projet", ou un élément global de même nom se trouve dans plusieurs modules, alors qu'il devrait être "privé"/caché.

    J'ai aussi oublié de préciser qu'il faut faire attention a ne pas placer des implémentations dans un header, vu que justement elles seront compilées dans chaque module ou a été inclus dans le header (et on aura une erreur de linker).
    On peut en revanche se le permettre avec des templates ou des fonctions inline. Cela peut avoir pas mal d'avantages.

  7. #7
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 766
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 766
    Par défaut
    Tu as oublié les include guard (<- lien Wiki)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Fonction de découpage en PL/SQL
    Par hindou90 dans le forum PL/SQL
    Réponses: 2
    Dernier message: 28/09/2010, 18h32
  2. Optimisation d'une fonction de découpage en sous-chaine
    Par FabaCoeur dans le forum Général Java
    Réponses: 9
    Dernier message: 05/01/2008, 14h00
  3. Réponses: 1
    Dernier message: 06/11/2007, 21h31
  4. Fonction de découpage d'un entier
    Par MayOL69bg dans le forum Langage
    Réponses: 5
    Dernier message: 25/04/2007, 15h24
  5. Réponses: 10
    Dernier message: 17/12/2003, 13h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo