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 :

containeur et h�ritage


Sujet :

C++

  1. #1
    Membre confirm�
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    95
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 95
    Par d�faut containeur et h�ritage
    Bonjour � tous,
    Je vous pose un probl�me, sans doute tr�s simple, mais j'ai un soucis et �a commence � me rendre fou. Je suis assez press� dans mon travail, c'est pour cela que je me permets de vous demander votre avis.

    J'ai une classe AbstractColumn qui est virtuelle pure. Ensuite, deux classes HColumn et DColumn qui h�ritent de AbstractColumn.

    Plus loin, dans une autre classe Array, j'ai un objet qui contient diff�rentes colonnes. J'ai impl�ment� cela avec un vector<AbstractColumn*> cols.
    N'existe-t-il pas une meilleure mani�re de stocker mes diff�rentes colonnes ?

    Actuellement, je devrais faire cols.push_back(&HColumn(blabla)); pour ajouter des �l�ments dans le vector, mais �a ne fonctionnera pas.

    Je vous remercie par avance.

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

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    4 302
    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 302
    Billets dans le blog
    2
    Par d�faut
    Bonjour,

    Citation Envoy� par Pg043 Voir le message
    N'existe-t-il pas une meilleure mani�re de stocker mes diff�rentes colonnes ?
    Il existe plusieurs fa�on de proc�der. La meilleure d�pend de ton contexte.
    . Celle que tu as choisi est la plus "classique".
    . boost::variant est sans doute le plus simple, mais c'est apparemment plut�t lent
    . il existe des solutions � base de typelist (voir ici par exemple).

    Citation Envoy� par Pg043 Voir le message
    cols.push_back(&HColumn(blabla)); ne fonctionnera pas.
    En g�neral, dans ton cas, on va plut�t faire un truc du style:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    cols.push_back(new HColumn(blabla));
    Ce qui signifie que c'est le vecteur col qui poss�de la nouvelle colonne.
    Mais l� encore, la meilleure fa�on de proc�der d�pendra beaucoup de ton contexte.


    edit: Dans tous les cas, lorsque tu cr�e un objet destin� � �tre stock� dans un conteneur, il est important de faire sp�cialement attention aux constructeurs, et en particulier le constructeur par copie.

  3. #3
    Membre confirm�
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    95
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 95
    Par d�faut
    Ah mais �videmment que je dois faire un new HColumn... D�sol� !
    Concernant ton edit sur les constructeurs par copie, j'imagine que cela signifie que je dois impl�menter le contructeur par copie de chacune de mes classes...
    Merci de ton aide

  4. #4
    Membre confirm�
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    95
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 95
    Par d�faut
    Ce premier probl�me �tant corrig�, je me permets de vous solliciter pour un second.

    J'ai donc 4 classes que voici : TempArray, qui contient un vector<TempAbstractColumn*>; une classe virtuelle pure TempAbstractColumn et deux classes filles, TempColumnH et TempColumnD ! C'est 4 classes me permettent (entre autre) de d�finir la configuration de mon tableau.

    Maintenant, je voudrais impl�menter la m�me hi�rarchie pour, non plus la configuration du tableau, mais le tableau lui m�me. J'aurai donc 4 nouvelles classes : Array qui h�ritera de TempArray et contiendra un vector<AbstractColumn*>; une classe virtuelle pure AbstractColumn qui h�ritera de TempAbstractColumn et deux classes filles, ColumnH et ColumnD qui h�riteront �galement respectivement TempColumnH et TempColumnD !

    Mon objectif est de pouvoir construire mon Array en fonction d'un TempArray. Probl�me : comment convertir le contenu du vector<TempAbstractColumn*> dans le vector<AbstractColumn*> ???

    Merci d'avance

  5. #5
    r0d
    r0d est d�connect�
    Membre exp�riment�

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    4 302
    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 302
    Billets dans le blog
    2
    Par d�faut
    Citation Envoy� par Pg043 Voir le message
    Concernant ton edit sur les constructeurs par copie, j'imagine que cela signifie que je dois impl�menter le contructeur par copie de chacune de mes classes...
    En v�rit� �a d�pend. Par exemple, si ces classes sont des POD et qu'elles n'ont pas de comportements farfelus, le copy-ctor par d�faut peut suffire. Idem pour l'op�rateur d'assignation. C'est pourquoi je dit qu' "il faut y faire attention": ce n'est pas forc�ment oblig�, mais il faut faire gaffe.
    Car en fait, lorsqu'on stocke des objets dans un conteneur et qu'on y applique des traitements, il va forc�ment y avoir des copies, plus ou moins cach�es.

  6. #6
    r0d
    r0d est d�connect�
    Membre exp�riment�

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    4 302
    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 302
    Billets dans le blog
    2
    Par d�faut
    Citation Envoy� par Pg043 Voir le message
    Probl�me : comment convertir le contenu du vector<TempAbstractColumn*> dans le vector<AbstractColumn*> ??
    Le d�tail de l'impl�mentation d�pend de ton contexte, mais grosso-modo �a devrait ressembler �:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void GenerateArray( const TempArray & src, Array & result )
    {
       for ( vector<TempAbstractColumn*>::const_iterator it = src.Begin(); it != src.End(); ++it )
          result.PushBack( new AbstractColumn( *it ) );
    // ce qui suppose que sont implémentés:
    // 1. des fonctions pour parcourir le tableau de TempAbstractCol contenu dans TempArray (ici j'ai fait comme s'il existait Begin() et End())
    // 2. une fonction pour ajouter des AbstractColumn à la classe Array (ici j'ai utilisé PushBack)
    // 3. un constructeur de AbstractColumn qui prend un TempAbstractColumn en paramètre
    }

  7. #7
    Membre confirm�
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    95
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 95
    Par d�faut
    Citation Envoy� par r0d Voir le message
    Le d�tail de l'impl�mentation d�pend de ton contexte, mais grosso-modo �a devrait ressembler �:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void GenerateArray( const TempArray & src, Array & result )
    {
       for ( vector<TempAbstractColumn*>::const_iterator it = src.Begin(); it != src.End(); ++it )
          result.PushBack( new AbstractColumn( *it ) );
    // ce qui suppose que sont implémentés:
    // 1. des fonctions pour parcourir le tableau de TempAbstractCol contenu dans TempArray (ici j'ai fait comme s'il existait Begin() et End())
    // 2. une fonction pour ajouter des AbstractColumn à la classe Array (ici j'ai utilisé PushBack)
    // 3. un constructeur de AbstractColumn qui prend un TempAbstractColumn en paramètre
    }
    1. j'utilise un vector, donc begin() et end() existe, je suis d'accord.
    2. idem pour le push_back, je suis d'accord.
    3. Mais ici, AbstractColumn est une classe virtuelle pure, donc, sans constructeur, ainsi, je n'ai pas de constructeur de AbstractColumn qui prend un TempAbstractColumn. Tout ce que je poss�de, c'est une classe ColumnH dont son constructeur prend un TempColumnH et une classe ColumnD dont un constructeur prend un TempColumnD !

    Pour le reste, je suis enti�rement d'accord, mais c'est pr�cis�ment sur ce troisi�me point que je n'arrive pas � r�soudre le probl�me...

    Merci pour tout

  8. #8
    r0d
    r0d est d�connect�
    Membre exp�riment�

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    4 302
    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 302
    Billets dans le blog
    2
    Par d�faut
    Mhh ok je vois le probl�me. Et � vrai dire, je ne vois pas trop comment faire...
    Il y aurait bien des solutions... mais c'est gore, j'ai un peu honte de proposer �a...
    Tu as l'air press�, alors voici une proposition, mais c'est vraiment horrible:
    Ajouter un moyen de diff�rencier une TempColumnH et une TempColumnD:
    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
    class TempAbstractColumn
    {
    protected:
       virtual const int Id() const = 0; // un identifiant, je le met en protected pour limiter la casse
    };
     
    class TempColumnH : public TempAbstractColumn
    {
       friend class ColumnFactory;
     
    private:
       const int Id() const { return 1; }
    };
     
    class TempColumnD : public TempAbstractColumn
    {
       friend class ColumnFactory;
     
    private:
       const int Id() const { return 2; }
    };
    Puis passer par une factory:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class ColumnFactory
    {
       public:
          static AbstractColumn * CreateColumn( const TempAbstractColumn * src )
          {
             if ( src->Id() == 1 )
                return new ColumnH( reinterpret_cast< const TempColumnH* >( src ) );
             else if ( src->Id() == 2 )
                return new ColumnD( reinterpret_cast< const TempColumnD* >( src ) );
             else
                // probleme
          }
    };
    Mais bon, le fait qu'on en arrive l� montre qu'il y a des soucis dans ta conception. Notemment, pourquoi tant d'h�ritage?

    ps1: tout ce que je propose ici n'est pas test�, et �a ne doit certainement pas compiler en l'�tat.

    ps2: je r�fute toute responsabilit� dans l'utilisation d'une telle technique, et je nierai, m�me sous la torture, avoir jamais �cris ce bout de code

  9. #9
    Membre confirm�
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    95
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 95
    Par d�faut
    Ok, merci de ton aide.
    J'avais commenc� � regarder l'histoire de factory, puis j'ai pu lire �a et l� que le reinterpret_cast n'est pas franchement terrible.
    Effectivement, je pense que je vais revoir un peu la conception avant d'aller plus loin.
    Merci tout de m�me

  10. #10
    Invit�
    Invit�(e)
    Par d�faut
    Pourquoi utiliser un reinterpret_cast ? Un static_cast conviendrait mieux dans ce cas... (ou un dynamic_cast lors du deboggage pour ne pas avoir de surprises si les identifiants ont �t� mal affect�s)

  11. #11
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    D�tails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par d�faut
    Salut,

    Ou sinon tu demandes de construire un Array au TempArray, qui va � son tour demander aux TempAbstractColumn de construire leur AbstractColumn qui leur correspond.

    MAT.

Discussions similaires

  1. template et h�ritage de containeur
    Par G�bix dans le forum C++
    R�ponses: 9
    Dernier message: 15/06/2012, 20h59
  2. [Postgresql]H�ritage
    Par lheureuxaurelie dans le forum PostgreSQL
    R�ponses: 13
    Dernier message: 02/10/2008, 09h18
  3. [Postgres] H�ritage + Cl�s
    Par k-reen dans le forum PostgreSQL
    R�ponses: 6
    Dernier message: 21/05/2003, 16h37
  4. Containeur pour un assemblage d'images
    Par Amenofis dans le forum Composants VCL
    R�ponses: 3
    Dernier message: 28/02/2003, 15h10
  5. H�ritage entre Forms
    Par BarBal dans le forum Composants VCL
    R�ponses: 7
    Dernier message: 29/08/2002, 17h44

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