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 :

Création d'un tableau d'objets contenant un paramètre au constructeur


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut Création d'un tableau d'objets contenant un paramètre au constructeur
    Bonjour à tous

    Habitué du C, je me mets un peu au C++ et je me heurte à des soucis de syntaxe (voire de possibilité)

    J'ai un objet recevant impérativement un paramètre à sa création. Exemple
    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class cXXX {
    public:
    	int n;
    	cXXX(int nn) : n(nn) {}
    };

    Je peux parfaitement créer une instance simple (ie cXXX x(123)) ou bien une instance allouée (ie cXXX *x=new cXXX(456)). Jusque là, ok.

    Maintenant je voudrais créer un tableau d'objets. Et là je me heurte au fait que mon objet reçoit un argument à sa création et je ne sais pas comment passer cet argument.
    J'aimerais bien que ce soit possible de façon intuitive (un truc comme cXXX tab[10](123)) mais bon je ne m'en sors pas (et quelque chose me dit que ce n'est pas possible).
    Je tente l'allocation dynamique avec new mais là aussi mes essais ne fonctionnent pas (ie cXXX *tab=new[10] cXXX(456)).

    Quelqu'un aurait-il la syntaxe qui me manque ?

    Merci
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  2. #2
    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
    Essaye ces 2 syntaxes

    Avec un tableau C, mais std::array c'est la même chose (<- à regarder)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cXXX tab[3] = {cXXX(123), cXXX(65), cXXX(4520)};

    Avec un tableau C++
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::vector<cXXX> tab(10, cXXX(456));

  3. #3
    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
    Hello,

    Si tu utilises std::vector, tu peux utiliser std::vector::emplace_back.
    Avec std::array, il faut initialiser ses valeurs directement : std::array<CXX, 3>> arr{CXX(1), CXX(2), CXX(3)};. Même chose pour un tableau C CXX arr[3] = {CXX(1), CXX(2), CXX(3)};.
    Si tu fais un new (mais il ne faudrait plus faire de new !), tu ne dois pas créer un tableau de CXX mais un buffer et utiliser le placement new (et donc tu réécris un cheap vector).
    Sinon, il faut ajouter un constructeur par défaut et une autre manière d'initialiser ton membre, avec une fonction init par exemple.
    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.

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par foetus Voir le message
    Avec un tableau C, mais std::array c'est la même chose (<- à regarder)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cXXX tab[3] = {cXXX(123), cXXX(65), cXXX(4520));
    Oui là je vois (et même je vois que j'aurais dû y penser vu que c'est pareil en C ) mais ça ne peut pas m'aller car la taille du tableau est dans un #define donc je peux pas coder "en dur" le remplissage.

    Citation Envoyé par foetus Voir le message
    Avec un tableau C++
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::vector<cXXX> tab(10, cXXX(456));
    Alors là c'est super. Je connaissais pas les vector (enfin je connaissais un peu l'idée) et je vois que ça marche pareil qu'un tableau mais en mieux
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class cXXX {
    public:
    	int n;
    	cXXX(int nn) : n(nn) {}
    };
     
    int main() {
    	std::vector<cXXX> tab(5, cXXX(456));
    	for (size_t i=0; i < 5; i++)
    		printf("i=%d, n=%d\n", i, tab[i].n);
    }

    Merci de ton aide C'est exactement ce qu'il me fallait. Juste savoir s'il faut le libérer à la fin (free/delete/destroy/del) ?

    Citation Envoyé par Bousk Voir le message
    Sinon, il faut ajouter un constructeur par défaut et une autre manière d'initialiser ton membre, avec une fonction init par exemple.
    Pour être honnête c'était comme ça que j'avais fait au départ mais bon je suis parti d'un code C que j'ai porté en Python et là c'était simple (tab=tuple(cXXX(123) for i in range(n))) et ensuite j'ai voulu le porter en C++ et là je me suis dit qu'il devait sûrement avoir l'équivalent et que ce serait plus sympa si le paramètre pouvait être passé directement à la création plutôt que tordre mon code pour le remplir après coup.
    Et je suis aussi en train de le porter en php

    Citation Envoyé par Bousk Voir le message
    tu ne dois pas créer un tableau de CXX mais un buffer et utiliser le placement new (et donc tu réécris un cheap vector).
    Je te demande pardon, mais là je suis totalement largué
    Merci à toi aussi
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  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
    Tu peux décider de l'adresse utilisée pour créer ton objet avec new.
    https://en.cppreference.com/w/cpp/language/new
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char buffer[sizeof(CXX)];
    CXX* ptr = new(buffer)CXX(1);
    assert(ptr == buffer);
    Par contre il faut alors appeler le destructeur manuellement.
    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
    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
    Citation Envoyé par Sve@r Voir le message
    Juste savoir s'il faut le libérer à la fin (free/delete/destroy/del) ?
    Non, la collection std::vector s'occupe de toutes les allocations pour toi afin d'agrandir/ de réduire le tableau.
    Tu as la méthode reserve pour lui donner 1 taille sans valeurs (<- 1 lien cplusplus.com en anglais)

    Donc ici , c'est 1 variable locale dans le main.


    Citation Envoyé par Sve@r Voir le message
    Je te demande pardon, mais là je suis totalement largué
    Il parle de surcharger l'opérateur operator new, qui est 1 fonction (<- lien cplusplus.com en anglais)
    En C++, pour 1 classe tu peux redéfinir tous les opérateurs : +, -, <=, ... et donc new.

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par foetus Voir le message
    En C++, pour 1 classe tu peux redéfinir tous les opérateurs : +, -, <=, ...
    Ouaip, comme en Python (et probablement dans tous les langages objets). Pas de souci.

    Citation Envoyé par foetus Voir le message
    et donc new.
    Noté (quand on y réfléchit on se dit "oui évidemment" mais encore eut-il fallu y réfléchir )

    Bon, pas évident de se mettre à une nouvelle syntaxe
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Juin 2011
    Messages : 760
    Par défaut
    Plutôt qu'une constante avec define, il vaut mieux utiliser une valeur inline constexpr, mais comme cette taille est connue à la compilation, il est toujours possible de construire un tableau remplit:

    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
     
    template<std::size_t... ints, class F>
    auto make_filled_array_impl(std::index_sequence<ints...>, F&& f)
    {
      return std::array{(void(ints), f())...};
    }
     
    template<std::size_t N, class F>
    auto make_filled_array(F&& f)
    {
      return make_filled_array_impl(std::make_index_sequence<N>(), f);
    }
     
    //std::array<cXXX, N> tab = ...
    auto tab = make_filled_array<N>([]{ return cXXX(123); });
    -> https://godbolt.org/z/Lh9cY6


    Citation Envoyé par Sve@r Voir le message
    En C++, pour 1 classe tu peux redéfinir tous les opérateurs : +, -, <=, ...
    Ouaip, comme en Python (et probablement dans tous les langages objets). Pas de souci.
    Non, la surcharge d'opérateur et la POO sont 2 choses différentes. Il y a plein de langage qui ne sont pas objets mais supportent la surcharge d'opérateur, et inversement. Php, Java, Javascript n'ont pas de surcharge des opérateurs mathématique par exemple, simplement parce que cela a rarement du sens en dehors des value-classes.

    Si j'ai 2 classes pour représenter des chaînes de caractère, la première classique et l'autre avec de la couleur, que devrait faire + ?
    - ColoredString + String = ColoredString, mais de quelle couleur va être la seconde partie de la chaîne ?
    - String + ColoredString = String, mais on perd la couleur
    - String + ColoredString = ColoredString, mais il faudra probablement que String connaissent ColoredString et toutes les éventuelles dérivées -> on fait sauter le O de SOLID
    - interdire le mélange, mais le principe de substitution disparaît

    Donc finalement, + ne fonctionnera bien qu'avec les objets du même type ou qu'on n'a préalablement défini, ce qui n'est pas exactement le principe de la POO.
    (faire des classes/objets != POO)

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 17/10/2016, 20h08
  2. Création d'un tableau d'objet
    Par daimado dans le forum Collection et Stream
    Réponses: 6
    Dernier message: 04/12/2015, 12h00
  3. [PHP 5.3] Création de tableau d'objets
    Par mika984 dans le forum Langage
    Réponses: 2
    Dernier message: 05/04/2012, 18h57
  4. Serialiser un objet contenant un tableau
    Par stdebordeau dans le forum Windows Forms
    Réponses: 2
    Dernier message: 09/09/2009, 20h29
  5. Création d'un tableau d'objet
    Par chronos7 dans le forum ActionScript 1 & ActionScript 2
    Réponses: 3
    Dernier message: 03/05/2006, 12h05

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