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 :

Declaration vs Definition (classe)


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2010
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 18
    Par défaut Declaration vs Definition (classe)
    Bonsoir à tous,

    Dans mon apprentissage du C++ je me heurte à un concept basique, sur lequel je pourrais faire l'impasse en prétextant que je sais "quoi faire pour que ça marche", mais sur lequel je voudrais lever toute ambiguité.

    Il s'agit de la différence entre une déclaration et une définition particulièrement dans le cas d'une classe.

    si j'écris :

    Je déclare une classe de type A.

    Si j'écris en revanche

    je définis une classe de type A.

    rien d'embêtant jusque la. Si je place la définition de cette classe dans un fichier .h e que je l'inclus dans deux fichiers sources différents, je n'aurais pas de pb à la compilation + édition des liens

    En revanche si je rajoute dans mon header, une définition de fonction, par exemple à la suite de la définition de ma classe. Disons :

    la j'aurais un problème à l'édition des liens, car la fonction aura été définie deux fois (une fois dans chaque fichier objet où elle aura été incluse).

    Pourquoi donc cela ne pose-t-il donc pas de problème pour le type classe(classe que j'ai également définie au même titre que ma fonction f) ? N'y a-t-il pas un principe de base en c++ qui interdit la double définition, et ce quelque soit le type?

    Merci et en espérant que ma question n'est pas trop stupide.


    Bonne soirée,

    Romain

  2. #2
    Membre éprouvé Avatar de Flow_75
    Femme Profil pro
    Ingénieure
    Inscrit en
    Mai 2005
    Messages
    1 100
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieure
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 100
    Par défaut
    Salut et bienvenu dans le monde merveilleux du C++

    Déja, par principe, et pour éviter les doubles déclarations il faut utiliser les balises :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #ifndef _FICHIER_H_
    #define _FICHIER_H_
    ...
    #endif

    Ensuite, Il faut séparer ta déclaration et ta définition dans deux fichiers distincts (respectivement h (ou hpp) et cpp).

    Dernierement pour définir une fonction il faut faire :


  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Août 2010
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 18
    Par défaut
    Salut,

    tout d'abord merci de ta réponse.

    Je suis bien d'accord avec toi, qu'il s'agit de ce qu'il faut faire, seulement je voudrais comprendre la chose suivante :

    pourquoi une définition de classe peut-être fait plusieurs fois (comprendre par : pourquoi je peux inclure un header contenant une définition de classe dans plusieurs fichiers sources sans avoir de souci à l'édition de liens) tandis que la même chose avec une fonction ou un type de base est rejetée par l'éditeur de liens.

    y-a-t-il une raison profonde à cela?

    C'est un détail, mais je voudrais être sur de bien comprendre

    Merci et bonne soirée,

    Romain

  4. #4
    Membre éprouvé Avatar de Flow_75
    Femme Profil pro
    Ingénieure
    Inscrit en
    Mai 2005
    Messages
    1 100
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieure
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 100
    Par défaut
    Salut,

    En faite, la déclaration et la définition interviennent à des endroits differents.

    L'un à la compilation, et l'autre à l'edition de liens.

    disons que tu déclares cela :

    dans le .h
    dans le .cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void fonc(int cpt)
    {
       printf("%i", cpt + 1);
    }
    Lorsque tu utilises dans ton programme, la fonction fonc, ton compilateur doit connaitre la définition de ta fonction utilisée (retour, nom, argument(s)) lors de la compilation.

    Donc, dans chaque fichier source où tu utilises ta fonction tu dois inclures ton .h

    Lorsque tu fais ton edition de liens, chaque fonction aura recu une signature unique (de par le retour, le nom et ses(son) argument(s) ).
    Ton editeur de liens fait la correspondance afin de relier chaque appel de fonction au code qui sera executer lors de l'appel.

    Si tu définis deux fois la meme fonction (qu'elle ai ou non le meme code) comment veux tu que l'editeur de liens fasse le choix entre les possibilités ?

  5. #5
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Citation Envoyé par Flob91 Voir le message
    Dernierement pour définir une fonction il faut faire :
    Ceci est une déclaration de fonction, pas une définition.



    Pour répondre au posteur, tu me sembles avoir compris où sont les définitions et ce qu'est une unité de traduction.

    L'ODR (one definition rules) est composé de différentes règles, elles disent en particulier que n'importe quels types d'entité ne peut être définie qu'une fois par unité de traduction, et que pour certains types d'entité (dont les fonctions, non inline, mais pas les classes), elles doivent être définient qu'une fois par programme.

    Ainsi tu vois que l'utilisation de gardes dans les fichiers de déclaration (.hpp), servent à protéger les définitions des classes contre l'ODR, mais qu'ils ne protègent en aucun cas l'éventuelle définition d'une fonction (non inline), raison pour laquelle ces dites fonction (non inline), doivent être définie dans un fichier de définition (.cpp), ce qui assure qu'elles ne seront définies que dans une unité de traduction (à moins de la définir deux fois dans le même fichier ...), et donc une seul fois dans tout le programme au final, respectant ainsi l'ODR.


    PS: Je marque des extensions possible pour les types de fichier, car je ne suis par certain que le vocabulaire fichier de déclarations / fichier de définitions soit "classique" (cependant je le trouve compréhensible et pas illogique).

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Août 2010
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 18
    Par défaut
    @flob90: C'est très clair, et exactement l'objet de ma question. J'ignorais l'existence de telles règles qui autorisent les classes (et d'autres types ?) à être potentiellement définies au sein de plusieurs unités de traduction (contrairement aux fonctions)

    Merci!


    @flob91 : je suis d'accord, mais ce n'est pas l'objet de ma question : ma question était liée au fait que l'éditeur de liens ne dit rien quand une classe se retrouve définie dans plusieurs modules objets, alors qu'il rejette ceci dans le cas d'une fonction ou type de base (pour les raisons que tu as citées).

    Romain

  7. #7
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    @Flob91: Tu as encore confondu définition et déclaration dans ton dernier message.

    @OP: Retient que le cas général c'est une seule définition par unité de traduction. En qu'il y a des exceptions qui demandent une seule définition par programme :
    - fonctions non inline (membre ou pas, template (*) ou pas)
    - variables avec un "external linkage" (basiquement les variables déclarées dans un espace de nom, voir l'espace global, sans static)
    - données membres statiques

    (*) en pratique ca s'applique rarement aux templates car il demande le système apporté par "export" qui n'est en pratique que très peu supporté par les compilateurs.

Discussions similaires

  1. declaration et definition de variable globale
    Par remitbo dans le forum C++
    Réponses: 0
    Dernier message: 11/12/2007, 23h12
  2. definition class return con
    Par djibril dans le forum JDBC
    Réponses: 1
    Dernier message: 18/10/2007, 12h00
  3. Réponses: 5
    Dernier message: 02/08/2007, 00h28
  4. Réponses: 7
    Dernier message: 30/12/2006, 14h48
  5. [Language][Définition]Classe métier
    Par thebloodyman dans le forum Langage
    Réponses: 11
    Dernier message: 14/12/2005, 13h00

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