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

Langage C++ Discussion :

Tableau et constructeurs sans arguments


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Avatar de wafiwafi
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    500
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 500
    Par défaut Tableau et constructeurs sans arguments
    Bonjour,
    Une petite question!
    Pourquoi dans le cas d'une création d'un tableau d'objets, on fait appel obligatoirement au constructeurs sans arguments?
    j'ai mis en pluriel "constructeurs" puisqu'un tableau peut contenir des objets de différents types (cas de l'héritage par exemple où il arrive qu'on référencie les objets par la classe mère.). D'ailleurs, je pense que c'est la raison des appels des constructeurs sans arguments; question de suivre une même politique et surtout de s'y trouver du point de vue création des différents objets dans le tableau; mais je ne suis pas sûr.
    Merci à vous

  2. #2
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    si j'ai bien compris ce que tu as dit, tu as raison.
    Lorsqu'un tableau est instancié, il va allouer la mémoire nécessaire. Pour cela, et à cause de certaines contraintes du c++ (en particulier celle de la contigüité des éléments en mémoire), c'est le constructeur par défaut (ce que tu appelles toi "constructeur sans argument") qui va être utilisé pour calculer cette allocation de mémoire.

    En vérité, dans un tableau C++, que ce soit un std::vector ou un tableau "C-style", tous les objets sont du même type. Lorsque tu fais allusion au stockage d'objets qui héritent d'une classe mère, en vérité, les éléments du tableau sont tous des pointeurs sur la classe mère, ce qui est un type à part entière (ce qui peut porter à confusion, c'est que le downcast est implicite en c++, donc parfois on a l'impression de stocker un pointeur sur une Fille alors qu'en vérité c'est un pointeur sur une Mere que l'on stocke).

  3. #3
    Membre éclairé
    Avatar de wafiwafi
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    500
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 500
    Par défaut
    Merci pour ta réponse.
    Lorsqu'un tableau est instancié, il va allouer la mémoire nécessaire. Pour cela, et à cause de certaines contraintes du c++ (en particulier celle de la contigüité des éléments en mémoire), c'est le constructeur par défaut (ce que tu appelles toi "constructeur sans argument") qui va être utilisé pour calculer cette allocation de mémoire.
    Tu parles de la contigüité en mémoire des objets du tableau?
    Comme tu le sais certainement, cette contiguïté est une vision conceptuelle que le compilateur/runtime fournit à l'utilisateur. Logiquement et puisqu'il s'agit de vision, elle ne participe pas à la réalité et donc je ne vois pas son intérêt dans la question (appel du constructeur par défaut); mon raisonnement est personnel et peut être erroné; tu veux certainement dire un truc que je n'ai pas compris.
    Pour moi, quand tu appelles un constructeur, il y a appel de code pour chaque objet. Et il vaut mieux appeler un seul code pour les objets de même type qu'allers chercher en mémoire un code pour chaque objet. C'est peut être une question d'optimisation (accès mémoire, branchements, importation de codes, ...
    Bien à toi

  4. #4
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    Comme tu le sais certainement, cette contiguïté est une vision conceptuelle que le compilateur/runtime fournit à l'utilisateur. Logiquement et puisqu'il s'agit de vision, elle ne participe pas à la réalité et donc je ne vois pas son intérêt dans la question (appel du constructeur par défaut); mon raisonnement est personnel et peut être erroné; tu veux certainement dire un truc que je n'ai pas compris.
    Cette contiguïté n'a rien de conceptuelle, du moins pas en C et en C++. Les objets sont réellements contigü en mémoire, d'où la rapidité d'accès aléatoire et les contraintes liées.
    Dans d'autres languages, elle peut être effectivement conceptuelle. Ce n'est pas le cas ici.

    Pour moi, quand tu appelles un constructeur, il y a appel de code pour chaque objet. Et il vaut mieux appeler un seul code pour les objets de même type qu'allers chercher en mémoire un code pour chaque objet. C'est peut être une question d'optimisation (accès mémoire, branchements, importation de codes, ...
    Je ne suis pas sur de comprendre ce que tu veux dire par là. Un constructeur "construit" une seule et unique instance d'objet. Si tu as n objects dans ton tableau, tu dois appeler forcément n constructeurs par défaut, un pour chacun de ces objets.

    Quand il sagit de pointeurs, ce sont les pointeurs qui sont construits. Si ce sont des pointeurs vers une classe mère d'autres classes, alors on peut assigner ces pointeurs à des instances de classes filles. Mais le tableau lui ne contiens bien que des pointeurs.

  5. #5
    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
    Citation Envoyé par wafiwafi Voir le message
    Merci pour ta réponse.


    Tu parles de la contigüité en mémoire des objets du tableau?
    Comme tu le sais certainement, cette contiguïté est une vision conceptuelle que le compilateur/runtime fournit à l'utilisateur. Logiquement et puisqu'il s'agit de vision, elle ne participe pas à la réalité
    Absolument pas

    S'il est vrai qu'il s'agit d'une vision de la manière dont la mémoire est représentée, elle participe néanmoins activement à la manière dont les différents éléments sont placés en mémoire:

    En effet, si un objet est de taille T et que tu déclares un tableau d'éléments dont le premier se trouve à l'adresse M, le deuxième doit se trouver à M + T, le troisième à M + (2 * T) et ainsi de suite.

    Deux éléments successifs de tableau ne prendront jamais place ailleurs qu'en deux adresse mémoire successives, en considérant comme successives le fait que deux adresses mémoires ne soient séparées que de exactement le nombre d'adresses nécessaire pour représenter l'ensemble des informations d'un objet.

    Il y a, il est vrai, un phénomène d'alignement qui assure le fait qu'un type primitif dont le nombre de bytes correspond à ce qu'un ordinateur peut traiter avec un registre se trouvera systématiquement à une adresse qui est multiple du nombre de byte traitable par le registre en question, mais les adresses restent tout à fait contigües:

    Si le phénomène d'alignement fait que la taille d'une structure proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct S
    {
        char c1; // 1 byte
        int i;   // évalué à 4 bytes
        char c2; // 1 byte
    };
    sera évaluée, sur une architecutre 32 bits, à 12 bytes, afin d'assurer l'adressage par multiples de 4 (qui est le nombre de bytes gérables en une fois par un registre); il n'en demeure pas moins qu'un tableau de 2 S utiliisera les adresses allant de M+0 à M+11 pour le premier et de M+12 à M+23 pour le second.
    et donc je ne vois pas son intérêt dans la question (appel du constructeur par défaut); mon raisonnement est personnel et peut être erroné;
    Il est, effectivement erroné, principalement parce que basé sur une idée fausse
    Pour moi, quand tu appelles un constructeur, il y a appel de code pour chaque objet. Et il vaut mieux appeler un seul code pour les objets de même type qu'allers chercher en mémoire un code pour chaque objet. C'est peut être une question d'optimisation (accès mémoire, branchements, importation de codes, ...
    Bien à toi
    C'est effectivement aussi une raison possible
    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

  6. #6
    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
    Par défaut
    Citation Envoyé par wafiwafi Voir le message
    Bonjour,
    Une petite question!
    Pourquoi dans le cas d'une création d'un tableau d'objets, on fait appel obligatoirement au constructeurs sans arguments?
    Parce qu'il faut bien en appeler un, et qu'il serait plus difficile de prévoir une syntaxe pour spécifier une valeur d'argument à chacun des éléments d'un tableau (à noter qu'avec C++0x, une telle syntaxe existera). A noter que si tu utilises des vecteurs, tu peux déjà construire les éléments par copie d'un élément de référence, plutôt que par le constructeur par défaut. Et qu'avec des tableaux à la mode C et des objets de type POD, tu peux aussi les initialiser directement (mais je suis moins certain).
    Citation Envoyé par wafiwafi Voir le message
    j'ai mis en pluriel "constructeurs" puisqu'un tableau peut contenir des objets de différents types (cas de l'héritage par exemple où il arrive qu'on référencie les objets par la classe mère.)
    Non. Un tableau ne contient qu'un seul type.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  7. #7
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Et qu'avec des tableaux à la mode C et des objets de type POD, tu peux aussi les initialiser directement (mais je suis moins certain).
    Oui, si ce n'est qu'un type POD n'a pas de constructeur défini par l'utilisateur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    struct point
    {
        int x;
        int y;
    };
     
    int main()
    {
        point tableau_c_pt[]={
            {1,2},
            {3,4}
        };
        return 0;
    }
    Citation Envoyé par JolyLoic Voir le message
    à noter qu'avec C++0x, une telle syntaxe existera
    Ca fera certainement parti des évolutions les plus appréciables.
    code C++0x déjà compilable avec gcc 4.4.X (pas testé avec visual 10) :
    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
    16
    17
    18
    19
    20
    21
    22
    #include <string>
    #include <vector>
    struct my_struct
    {
       my_struct(){}
       my_struct(std::string s_):i{0},s(s_){}
       my_struct(int i_):i{i_}{}
       my_struct(int i_, std::string s_):i{i_},s(s_){}
     
       int i;
       std::string s;
    };
    int main()
    {
       std::vector<my_struct> vect={
          1, // appel de my_struct(int)
          std::string("tutu"), // appel de my_struct(std::string)
          {1,std::string("1")}, // appel de my_struct(int, std::string)
          {} // appel de my_struct()
       }; // vecteur de 4 éléments !
       return 0;
    }
    C'est pas C++0x ?

  8. #8
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    code C++0x déjà compilable avec gcc 4.4.X (pas testé avec visual 10) :
    Ca ne fera pas partie des features C++0x dispo dans vc10. Peut être dans un Service Pack futur, sait on jamais.

  9. #9
    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
    Citation Envoyé par Klaim Voir le message
    Ca ne fera pas partie des features C++0x dispo dans vc10. Peut être dans un Service Pack futur, sait on jamais.
    Il faut l'espérer...

    Mais, tant que la norme n'est pas finalisée...
    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

  10. #10
    Membre éclairé
    Avatar de wafiwafi
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    500
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 500
    Par défaut
    Je vous remercie pour toutes ces réponses.
    Néanmoins, un dilemme m'est posé!
    Lors d'une discussion au forum Langages, j'ai posé une question qui s'intitule :
    Le fichier binaire produit par le compilateur
    Le message date du 10/10/2009.
    Le dernier intervenant en question est Mac LAK.
    Je vous invite à regarder le dernier message posté qui explique le fonctionnement mémoire/ compilateur; il n'est pas du tout en phase avec vous.
    Je vous laisse d'abord le lire et me dire votre avis.

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

Discussions similaires

  1. applet et constructeur sans argument
    Par new_wave dans le forum Applets
    Réponses: 2
    Dernier message: 09/05/2012, 08h58
  2. Pas de compilation sans constructeur sans argument!
    Par bertry dans le forum Débuter
    Réponses: 3
    Dernier message: 28/12/2011, 11h33
  3. Réponses: 19
    Dernier message: 13/12/2010, 20h24
  4. Signature d'une fonction sans argument
    Par cj227854 dans le forum C++
    Réponses: 5
    Dernier message: 20/10/2005, 17h01
  5. Réponses: 5
    Dernier message: 04/11/2004, 15h36

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