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 :

Classe Template et fonction virtuelle cach�e


Sujet :

C++

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre habitu�
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    7
    D�tails du profil
    Informations personnelles :
    �ge : 38
    Localisation : France, Rh�ne (Rh�ne Alpes)

    Informations forums :
    Inscription : Mars 2010
    Messages : 7
    Par d�faut Classe Template et fonction virtuelle cach�e
    Bonjour,

    J'ai cod� une classe template permettant d'acc�der � une table de base de donn�es.

    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
     
    template <class T>
    class IDbfIO
    {
    public:
    	/// \brief Ecrit un enregistrement (non impl)
    	virtual writeRecord( const T & data )
    	{
    	}
     
    	/// \brief Modifie un enregistrement (non impl)
    	virtual void editRecord( const T & data )
    	{
    	}
     
    	/// \brief Lit un enregistrement (non impl)
    	virtual void readCurrentRecord( T & data )
    	{
    	}
     
    	/// \brief Lit tous les enregistrements dans un vecteur
    	virtual void readAllRecords( vector<T> & aData )
    	{
    		int i = 0;
    		aData.resize( m_pTable->RecordCount );
     
    		m_pTable->First();
     
    		// lecture du fichier
    		while ( !m_pTable->Eof )
    		{
    			readCurrentRecord( aData.at( i ) );
    			i++;
    			m_pTable->Next();
    		}
    	}
     
    	/// \brief Lit tous les enregistrements dans une map
    	virtual void readAllRecords( map<AnsiString,T> & mapData )
    	{
    		AnsiString strKey = "";
    		T data;
     
    		m_pTable->First();
     
    		// lecture du fichier
    		while ( !m_pTable->Eof )
    		{
    			readCurrentRecord( strKey, data );
     
    			if( !mapData.count( strKey ) )
    			{
    				mapData[strKey] = data;
    			}
    			else
    			{
                                                 //log
    			}
     
    			m_pTable->Next();
    		}
    	}
    };
    Cette architecture a un double int�r�t :
    - me permettre de factoriser du code ( par exemple : les fonctions lisant l'int�gralit� de la table ).
    - forcer les classes filles impl�mentant IDbfIO a surcharger des fonctions (par exemple : readCurrentRecord() ).

    Par exemple voici une classe fille :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class CDbfService : public IDbfIO<CDataService>
    {
    public:
    	CDbfService();
    	~CDbfService();
     
    	/// \brief Specialisation de lecture pour les CDataService
    	/// \param data : donnees du service
    	void readCurrentRecord( CDataService & data );
    };
    Elle supplante readCurrentRecord(). Jusque l� pas de soucis, c'est lorsqu'elle supplante readAllRecords( vector<CDataService> & aData ) que j'ai un soucis.

    En effet, j'ai une warning me pr�cisant que la fonction readAllRecords( map<AnsiString,T> & mapData ) est cach�e.

    J'ai donc creus� le sujet et compris qu'il fallait que je rajoute la ligne

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    using CDbfIO::readAllRecords( map<AnsiString,T> & mapData );
    dans la classe fille pour que la fonction virtuelle ne soit plus cach�e.

    N�anmoins le compilateur de C++ builder 2010 me jette lorsque j'ajoute cette ligne de code. Sachant que j'ai �galement essay� d'ajouter :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    using CDbfIO<T>::readAllRecords( map<AnsiString,T> & mapData );
    et

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    using CDbfIO<CDataService>::readAllRecords( map<AnsiString,CDataService> & mapData );
    Pensez-vous que c'est une erreur syntaxe de ma part ou une limitation du compilateur de C++ builder 2010 ?

    A noter que pour l'instant je m'en suis tir� en d�clarant, dans IDbfIO, les fonctions :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
     
    virtual void readAllRecordsInVector( vector<T> & aData )
    virtual void readAllRecordsInMap( map<AnsiString,T> & mapData )
    au lieu de

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
     
    virtual void readAllRecords( vector<T> & aData )
    virtual void readAllRecords( map<AnsiString,T> & mapData )
    Mais je trouve cette solution lourde car elle m'oblige � cr�er une nouvelle fonction pour chaque type de conteneur alors que je voulais juste surcharg� la fonction readAllRecords().

    Merci d'avance !

  2. #2
    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
    Salut,
    La fonction virtuelle de la classe fille doit avoir la m�me signature que la classe m�re, sans quoi elle est effectivement cach�e !
    Donc ce devrait �tre :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    //CDbfService 
    virtual void readAllRecords( vector<CDataService> & aData );
    Ou faire 2 fonctions virtuelles comme tu l'as fait
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    virtual void readAllRecordsInVector( vector<T> & aData )
    virtual void readAllRecordsInMap( map<AnsiString,T> & mapData )
    Comme les fonctions g�n�riques ne peuvent �tre virtuelles, tu ne peux malheureusement pas faire :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    template<template<typename > cont
    virtual void readAllRecordsInVector( cont<T> & aData ); // erreur : ne compile pas !!
    Voir : Les fonctions virtuelles en C++ : Fonctions virtuelles et fonctions g�n�riques (template)


    Une solution int�ressante peut �tre de passer par une classe trait pour ta classe de base sp�cifiant le type effectif utilis� (code � la vol�) :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    template <class T, typename traits_t_>
    class IDbfIO
    {
    public:
    	/// \brief Lit tous les enregistrements dans un vecteur
    	virtual void readAllRecords( typename traits_t::type_read_all & aData )
    Puis :
    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
     
    template<class T1,T2>
    struct	map_trait
    {
        typedef std::map<T1,T2> type_read_all;
    };
    class CDbfService : public IDbfIO<CDataService,map_trait<AnsiString,CDataService> >
    {
    public:
    	CDbfService();
    	~CDbfService();
     
    	/// \brief Specialisation de lecture pour les CDataService
    	/// \param data : donnees du service
    	virtual void readAllRecords( std::map<AnsiString,CDataService& aData );
    };
    Sachant que si tout est d�termin� � la compilation, alors il est peut �tre int�ressant de mettre les fonctions en policy. Cf Classes traits et politiques par Alp

    Autre lecture qui peut �tre int�ressante : F.A.Q : Qu'est-ce que le CRTP ?

  3. #3
    Membre habitu�
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    7
    D�tails du profil
    Informations personnelles :
    �ge : 38
    Localisation : France, Rh�ne (Rh�ne Alpes)

    Informations forums :
    Inscription : Mars 2010
    Messages : 7
    Par d�faut
    Merci beaucoup pour cette r�ponse.

    Je pense finalement passer par un all�gement de mon architecture. En effet, je pense supprimer le template au niveau de ma classe IDbfIO car niveau factorisation du code m�me si c'est puissant c'�tait plus pour impl�menter un cas d'�cole.... ( on se fait plaisir comme on peut ).

    N�anmoins cette architecture m'obligeait par exemple � supplanter la fonction readAllRecords() si je voulais la sp�cialiser. J'aimerais donc pouvoir garder ce m�canisme afin d'avoir des classes filles ayant des noms de fonctions homog�nes.

    J'aimerais donc avoir le m�canisme suivant :

    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
     
    class CMere
    {
          template <class T>
          virtual readAllRecords( map<T> & data );
    };
     
    class CFille1
    {
         readAllRecords( map<CData1> & data );
    };
     
    class CFille2
    {
         readAllRecords( map<CData2> & data );
    };
    A noter que CData1 et CData2 n'ont rien en commun.

    N�anmoins d'apr�s tes dires, ce m�canisme est impossible en C++. As-tu donc une id�e d'architecture logicielle qui me permettrait d'avoir ce fonctionnement ?

    Je me souviens, dans un autre cas, avoir r�sout ce probl�me en faisant h�riter CData1 et CData2 d'une interface IData. Puis en impl�mentant la fonction :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
     
    class CFille2
    {
         readAllRecords( map<IData> & data );
    };
    avec un dynamic_cast vers CData2 dans le corps de la m�thode. N�anmoins je trouve cette solution plut�t in�l�gante pour ne pas dire d�gueulasse .

    Merci d'avance !

  4. #4
    Membre Expert
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 45
    Localisation : France, Essonne (�le de France)

    Informations professionnelles :
    Activit� : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Par d�faut
    virtual et template font rarement bon m�nage. Ici, as tu besoin d'un h�ritage ou un composant g�n�rique ne serait-il pas suffisant ?

  5. #5
    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 Joel F Voir le message
    virtual et template font rarement bon m�nage.
    Et m�me carr�ment, comme pr�sent� ici, sont impossibles : une fonction g�n�rique ne peut �tre virtuelle.
    @benbarate : sans plus d'�l�ments, je vois diff�rentes possibilit�s :
    -> les classes politiques&traits ;
    -> le CRTP ;
    -> le pimpl idiom ou un DP de type d�l�gation.

  6. #6
    Expert confirm�

    Inscrit en
    Novembre 2005
    Messages
    5 145
    D�tails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par d�faut
    Citation Envoy� par benbarate Voir le message
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
     
    template <class T>
    class IDbfIO
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
     
    class CDbfService : public IDbfIO<CDataService>
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    using CDbfIO<CDataService>::readAllRecords( map<AnsiString,CDataService> & mapData );
    Pensez-vous que c'est une erreur syntaxe de ma part ou une limitation du compilateur de C++ builder 2010 ?

    D'o� vient le CDbfIO? Je n'ai vu que des IDbfIO avant.

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    using IDbfIO<CDataService>::readAllRecords;
    Devrait faire ce qu'il faut.

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. fonction virtuelle cach�e
    Par Kalite dans le forum C++
    R�ponses: 6
    Dernier message: 18/07/2011, 09h03
  2. class template et fonction amie
    Par sleepless dans le forum C++
    R�ponses: 5
    Dernier message: 19/11/2010, 13h37
  3. R�ponses: 24
    Dernier message: 15/03/2007, 15h43
  4. [Classes] - Fonctions virtuelles et d�riv�es
    Par buzzkaido dans le forum C++
    R�ponses: 2
    Dernier message: 18/01/2007, 21h51
  5. Probl�mes de fonctions membres de classe templates, gcc3.3.6
    Par yves.dessertine dans le forum Autres �diteurs
    R�ponses: 12
    Dernier message: 17/10/2005, 21h36

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