Problème de généricité avec les templates
Bonjour,
Pour la conception d'une application d'affichage de données issues de trames réseaux, je souhaiterais faire quelque chose d'assez générique.
Je suis donc parti sur l'utilisation de templates et ai procédé de la sorte :
Une classe pour représenter des données de type traces :
Code:
1 2 3 4 5 6 7 8 9 10
| class QTraceData
{
public :
quint8 m_type;
QString m_date;
QString m_time;
QString m_file;
quint32 m_line;
QString m_msg;
}; |
Un template pour décoder/encoder les données :
Code:
1 2 3 4 5 6 7 8 9
| template <typename T>
class QDataDecoder
{
public :
virtual ~QDataDecoder() {}
virtual T* decode(bool&, const QByteArray&) const = 0;
virtual bool encode(const T*, QByteArray&) const = 0;
}; |
Une classe dérivée pour décoder/encoder les traces :
Code:
1 2 3 4 5 6
| class QTraceDecoder : public QDataDecoder<QTraceData>
{
public :
virtual QTraceData* decode(bool&, const QByteArray&) const;
virtual bool encode(const QTraceData*, QByteArray&) const;
}; |
Un template pour représenter le modèle de données :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| template <typename T>
class QDataTableModel : public QAbstractTableModel
{
public :
QDataTableModel(QObject* parent = 0)
: QAbstractTableModel(parent) {}
virtual int rowCount(const QModelIndex&) const
{
return m_data.size();
}
virtual bool insertRow(const T* data)
{
// insert data in m_data
}
protected :
QList<const T*> m_data;
}; |
Une classe dérivée pour représenter le modèle de traces :
Code:
1 2 3 4 5 6 7 8 9 10
| class QTraceTableModel : public QDataTableModel<QTraceData>
{
public :
QTraceTableModel(QObject* parent = 0);
virtual int columnCount(const QModelIndex&) const;
virtual QVariant data(const QModelIndex&, int) const;
QVariant headerData(int, Qt::Orientation, int) const;
bool setData(const QModelIndex&, const QVariant&, int);
}; |
Cette partie pour l'instant me plaisait bien, mais voilà, elle entraîne un manque de généricité au niveau du module ou de la façade censée être le point d'entrée pour la communication avec les autres modules.
J'ai, au départ, une classe pour la façade :
Code:
1 2 3 4 5 6 7 8
| class QModelFacade : public Common::QFacade
{
public :
QModelFacade() : Common::QFacade() {}
public slots :
virtual void interpretData(const QByteArray&) = 0; // appelée lors de la réception d'une trame réseau par le module Network
}; |
Ensuite, et c'est ici que ça se gâte :P, comme je n'arrivais pas à implémenter de façon générique la méthode interpretData avec les templates QDataDecoder et QDataTableModel (car je dois leur définir un type précis), j'ai créé, à contre coeur^^, une classe dérivée pour manipuler QTraceDecoder et QTraceTableModel :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class QTraceModelFacade : public QIModelFacade
{
public :
QTraceModelFacade();
~QTraceModelFacade();
public slots :
virtual void interpretData(const QByteArray&);
public :
QTraceTableModelFacade* m_tableModelFacade;
private :
QTraceDecoder* m_decoder;
}; |
Au passage, je retrouve la même difficulté avec QTraceTableModelFacade, créée faute d'avoir trouvé le moyen de garder une classe générique QTableModelFacade.
Ce manque de généricité entraîne, pour un changement de type de données, beaucoup de modifications à faire.. Encore devoir refaire une classe pour décoder ou une classe pour le modèle de ces nouvelles données d'accord, mais devoir recréer une classe façade ce n'est pas normal.
Je ne maîtrise surement pas assez bien les templates pour contourner cette difficulté et c'est pourquoi je me permets de faire appel à vos connaissances :).
Merci :)