Fonction template virtuelle... comment l'éviter ?
Bonjour,
Je viens d'apprendre à mes dépends un article de la norme C++ (14.5.2 p 3) : "A member function template shall not be virtual."
En effet j'ai défini une classe CountedPointer template, un pointeur intelligent avec comptage de référence. Problème : je ne veux pas imposer à l'utilisateur de cette classe que la destruction du pointeur se traduise par un "delete" sur l'élément pointé. J'ai donc défini une virtuelle _destroyPointedObject() que l'utilisateur peut redéfinir :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| template <class T>
class CountedPointer
{
private:
int* _counter;
// Méthode virtuelle de destruction de l'objet pointé
virtual void _destroyPointedObject(T*);
protected:
T* _pointedObject;
public:
// ..... plein de jolis constructeurs, destructeurs, opérateurs .....
}; |
Exemple d'utilisation pour un statement Oracle (API OCCI). On n'a pas le droit de deleter un statement Oracle, il faut le releaser avec terminateStatement, donc on dérive et on redéfinit _destroyPointedObject() :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class NamedStatement : public CountedPointer<Statement>
{
private:
string _name;
// Redéfinition de la méthode de destruction de l'objet pointé
void _destroyPointedObject(Statement*);
public:
// .... blablabla ....
};
void NamedStatement::_destroyPointedObject(Statement* pointedStatement)
{
pointedStatement->getConnection()->terminateStatement(pointedStatement);
} |
Je sais maintenant que ce code est faux à cause de la règle sus-citée, qui fera que la méthode finalement appelée sera celle de la classe mère, et qu'on va donc deleter sauvagement notre statement. Mon problème est : comment faire autrement ?? Connaissez-vous une méthode "classique" permettant de s'affranchir rapidement de ce problème ?
La seule solution que je vois serait d'imposer l'utilisation du delete, puis de passer par un adapteur qui encapsulerait le statement et appelerait terminateStatement() dans son desctructeur. Mais cela m'oblige à recoder toutes les classes que nous avons dérivée de ce CountedPointer jusqu'à présent (hé oui car comme tout bug mémoire qui se respecte, celui-ci ne s'est manifesté qu'après plusieurs mois à l'occasion d'une passe Purify). Si vous voyez une solution plus rapide en terme d'intégration, je suis preneur...
Merci