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 :

Initialisation statique d'objet avec constructeur


Sujet :

C++

  1. #1
    Membre confirmé
    Avatar de Captain'Flam
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Février 2011
    Messages : 273
    Points : 455
    Points
    455
    Billets dans le blog
    1
    Par défaut Initialisation statique d'objet avec constructeur
    Bonjour,

    je cherche à créer un tableau d'objets initialisés statiquement lors de la déclaration.
    Et je tombe sur un comportement que je ne m'explique pas !
    Voici un exemple minimal qui met en évidence ce comportement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <stdio.h>
     
    struct Pair
        {
        Pair ( int x = 0 , int y = 0 )    { _x = x ; _y = y ;}
        int _x,_y ;
        } ;
     
    void main ()
        {
        Pair p [2] = { (1,2),(3,4) } ;
        printf("(%d,%d)  (%d,%d)\n",p[0]._x,p[0]._y,p[1]._x,p[1]._y ) ;
        }
    Sur la console j'obtiens :Alors là...
    Quelqu'un pourraît-il m'expliquer ce phénomène ?
    Pourquoi sont-ce les secondes valeurs d'initialisation que je retrouve dans les premiers champs de mon objet ?

    Merci d'avance.

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Salut

    Ton code ne peut pas fonctionner en C car il s'agit ici de C++. En C, les classes n'existent pas. Or, ici, dans ce contexte, struct est bien une classe, avec son constructeur.

    Où as-tu appris à programmer en C ?

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2011
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2011
    Messages : 29
    Points : 63
    Points
    63
    Par défaut
    Salut,
    Ton code ne peut pas fonctionner en C car il s'agit ici de C++. En C, les classes n'existent pas. Or, ici, dans ce contexte, struct est bien une classe, avec son constructeur.
    Ce n'est pas tout à fait vrai, ici c'est bel et bien du C, syntaxiquement ce code fonctionne. Tant que les attributs "public", "private", "protected", etc ne sont pas dans le code, il est possible de remplacer "class" par "struct", d'ailleurs une structure peut très bien contenir des fonctions et des variables, elle est faite pour ça même

    De plus en C les constructeurs et destructeurs existent, certe pas comme en C++, mais existent :

    si une fonction est déclarée comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static type nom_fonction(void) __attribute__((constructor));
    ou comme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static type nom_fonction(void) __attribute__((destructor));
    fonctionne comme un constructeur ou un destructeur C++ à la fin de l'execution.

    Pour t'en assurer tu peux tester ce code et voir le résultat.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #include <stdio.h>
     
    static void fonction(void) __attribute__((destructor));
     
    main() {
     
    printf ("main\n");
     
    return 0;
    }
     
    void fonction(void){
     
        printf("fonction\n");
    }
    Sinon pour ton problème Captain'Flam, une chose me semble étrange, tu déclare un tableau à une dimension et l'exploite comme s'il en avait deux ???

    C++dialement

  4. #4
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2010
    Messages
    254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2010
    Messages : 254
    Points : 538
    Points
    538
    Par défaut
    a ceci prêt que je ne pense pas que ce soit très portable. Peut être que certains standard du C l'autorisent mais pas forcément tous. quand aux __attibute__, j'imagine que ce sont des attributs gcc et donc pas forcément tous les compilos l'accepteront. (d'ailleurs gcc me dit que ça va pas).

    Ceci est un code typiquement C++.

  5. #5
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Pour remettre ce code en C standard, on a
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <stdio.h>
    typedef struct Pair
    {
        int _x,_y ;
    }Pair ;
     
    int main (void)
    {
        Pair p [2] = { (1,2),(3,4) } ;
        printf("(%d,%d)  (%d,%d)\n",p[0]._x,p[0]._y,p[1]._x,p[1]._y ) ;
        return 0;
    }
    qui donnera comme affichage
    (2,4) (0,0)
    Dans ce code (1,2), la ',' n'est pas un séparateur de la liste d'initialisation, mais l'opérateur , (virgule) et le résultat de l'évaluation est 2.
    La liste d'initialisation comporte donc deux éléments seulement (1,2) et (3,4) qui s'évaluent respectivement à 2 et 4. L'autre élément Pair du tableau p n'est pas explicitement initialisé et est alors initialisé par défaut à {0,0}

    Par contre avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Pair p [2] = {  {1,2},{3,4} } ;
    on aurait comme affichage
    (1,2) (3,4)

  6. #6
    Membre confirmé
    Avatar de Captain'Flam
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Février 2011
    Messages : 273
    Points : 455
    Points
    455
    Billets dans le blog
    1
    Par défaut
    Toutes mes excuses, je me suis trompé de forum !

    Effectivement, mon code est bien du c++...

    Et effectivement, (1,2) est bien interprété comme 2 en tant que seconde opérande de l'opérateur virgule.

    Et effectivment, c'est avec {1,2} que j'aurais pu initialiser mon objet, mais comme il y a un constructeur, c'est interdit.

    En fait, le code c++ correct serait plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Pair p [2] = { Pair(1,2),Pair(3,4) } ;
    En tous cas, merci à tous de vos réponses précises et éclairantes !

  7. #7
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Citation Envoyé par Pop360 Voir le message
    Salut,

    Ce n'est pas tout à fait vrai, ici c'est bel et bien du C, syntaxiquement ce code fonctionne. Tant que les attributs "public", "private", "protected", etc ne sont pas dans le code, il est possible de remplacer "class" par "struct", d'ailleurs une structure peut très bien contenir des fonctions et des variables, elle est faite pour ça même
    Absolument pas. Ce code n'est pas du C, il est faux syntaxiquement. Et une structure ne peux en aucun cas contenir une fonction en C (mais en C++, si).

    Ce que tu décris c'est simplement du C++ sans classes, mais ce n'est pas pour autant du C.

  8. #8
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2011
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2011
    Messages : 29
    Points : 63
    Points
    63
    Par défaut
    Autant pour moi, sur le coup j'ai confondu fonctions et pointeurs de fonction.
    Ce que j'ai voulu dire c'est qu'une structure peut contenir des pointeurs de fonction, et des variables. Et en effet, la fonction pointée ne se trouve pas dans la structure.

    Et sinon Capt'ain Flam si tu codes en C++, pourquoi ne pas utiliser de classes ?

  9. #9
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    A noter qu'en C++11, même en présence d'un constructeur, le code indiqué marchera. Tout ce qui est initialisation a été revu et est bien plus puissant.

  10. #10
    Membre confirmé
    Avatar de Captain'Flam
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Février 2011
    Messages : 273
    Points : 455
    Points
    455
    Billets dans le blog
    1
    Par défaut
    Tout ce qui est initialisation a été revu et est bien plus puissant.
    Mmm ! ça donne envie ! malheureusement, au boulot je code sous Visual Studio, qui est un super EDI mais a toujours 12 métros de retard en matière de norme.
    Du coup, je pense que C++11 ce sera en 3011 pour moi

  11. #11
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Citation Envoyé par Captain'Flam Voir le message
    malheureusement, au boulot je code sous Visual Studio, qui est un super EDI mais a toujours 12 métros de retard en matière de norme.
    Tu exagères. Visual C++ 10 est sorti avec pas mal de nouveautés de C++11, qui s'appelait encore à l'époque C++0x...

  12. #12
    Membre confirmé
    Avatar de Captain'Flam
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Février 2011
    Messages : 273
    Points : 455
    Points
    455
    Billets dans le blog
    1
    Par défaut
    C'est vrai, le truc, c'est que nous ne changeons de version de Visual que très rarement, et encore, pour passer à une version déjà ancienne...
    Donc, c'est plutôt la faute du boss que de microsoft...

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

Discussions similaires

  1. objet avec constructeur surchargé
    Par membreComplexe12 dans le forum C++
    Réponses: 9
    Dernier message: 16/03/2013, 21h16
  2. Initialisation d'un tableau avec constructeurs
    Par Kalith dans le forum Langage
    Réponses: 17
    Dernier message: 06/12/2012, 19h40
  3. objet literal et objet avec constructeur
    Par hellalaboy dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 27/07/2011, 14h31
  4. var_export et les objets avec constructeurs
    Par gomodo dans le forum Langage
    Réponses: 2
    Dernier message: 15/08/2009, 12h04
  5. Réponses: 9
    Dernier message: 22/12/2005, 22h20

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