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 :
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 : 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 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 ..... };
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 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
Partager