Mon problème est relativement simple.
Je suis en train d'écrire une bibliothèque générique, et celle-ci utilise les smart_ptr du tr1 (ou de boost, puisque ce sont les mêmes)
Seulement, à l'initialisation (constructeur donc) de la classe, je souhaite initialiser le constructeur de shared_ptr en lui refilant une méthode (virtuelle) de destruction, au cas ou le shared_ptr servirait à gérer une structure, du genre SDL_Surface, qui ne s'initialise ni ne se détruit pas de façon simple, mais en utilisant des fonctions qui "remplacent" malloc et free.
J'ai donc un constructeur de classe template <_Tp> qui initialise un shared_ptr<_Tp> en lui passant l'adresse d'un deleter virtuel pur nommé classe<_Tp>::Free.
Evidement, ça merde à la compilation, et je suis presque sûr qu'il s'agit d'une erreur de logique très bête.
En même temps, j'ai un sacré mélange: template, fonction virtuelle pure, shared_ptr, deleter... et je dois admettre que je ne suis pas habitué à l'utilisation des shared_ptr :/
Bref, voici le bout de code incriminé:
Le bout de code qui instancie le code précédent:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 template <typename _Tp> __bitmap<_Tp>::__bitmap() :m_Surface((_Tp*)(0),&__bitmap<_Tp>::Free) { }
Et les erreurs affiliées:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 __sdl_bitmap::__sdl_bitmap():__bitmap<SDL_Surface>() { }
Petites précisions:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 /usr/include/c++/4.6/tr1/shared_ptr.h||In constructor std::tr1::__shared_count<_Lp>::__shared_count(_Ptr, _Deleter) [with _Ptr = SDL_Surface*, _Deleter = void (__bitmap<SDL_Surface>::*)(SDL_Surface*), __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]:| /usr/include/c++/4.6/tr1/shared_ptr.h:569|44|instantiated from std::tr1::__shared_ptr<_Tp, _Lp>::__shared_ptr(_Tp1*, _Deleter) [with _Tp1 = SDL_Surface, _Deleter = void (__bitmap<SDL_Surface>::*)(SDL_Surface*), _Tp = SDL_Surface, __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]| /usr/include/c++/4.6/tr1/shared_ptr.h:1006|30|instantiated from std::tr1::shared_ptr<_Tp>::shared_ptr(_Tp1*, _Deleter) [with _Tp1 = SDL_Surface, _Deleter = void (__bitmap<SDL_Surface>::*)(SDL_Surface*), _Tp = SDL_Surface]| ../pfen/bitmap_base.h:76|42|instantiated from __bitmap<_Tp>::__bitmap() [with _Tp = SDL_Surface]| /home/berenger/devel/C_Cpp/pfen/sdlimplementation/sdlbitmap.cpp:4|24|instantiated from here| /usr/include/c++/4.6/tr1/shared_ptr.h|328|error: must use .* or ->* to call pointer-to-member function in __d (...), e.g. (... ->* __d) (...)| /usr/include/c++/4.6/tr1/shared_ptr.h||In member function void std::tr1::_Sp_counted_base_impl<_Ptr, _Deleter, _Lp>::_M_dispose() [with _Ptr = SDL_Surface*, _Deleter = void (__bitmap<SDL_Surface>::*)(SDL_Surface*), __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]:| /home/berenger/devel/C_Cpp/pfen/sdlimplementation/sdlbitmap.cpp:78|1|instantiated from here| /usr/include/c++/4.6/tr1/shared_ptr.h|264|error: must use .* or ->* to call pointer-to-member function in ((std::tr1::_Sp_counted_base_impl<SDL_Surface*, void (__bitmap<SDL_Surface>::*)(SDL_Surface*), (__gnu_cxx::_Lock_policy)2u>*)this)->std::tr1::_Sp_counted_base_impl<SDL_Surface*, void (__bitmap<SDL_Surface>::*)(SDL_Surface*), (__gnu_cxx::_Lock_policy)2u>::_M_del (...), e.g. (... ->* ((std::tr1::_Sp_counted_base_impl<SDL_Surface*, void (__bitmap<SDL_Surface>::*)(SDL_Surface*), (__gnu_cxx::_Lock_policy)2u>*)this)->std::tr1::_Sp_counted_base_impl<SDL_Surface*, void (__bitmap<SDL_Surface>::*)(SDL_Surface*), (__gnu_cxx::_Lock_policy)2u>::_M_del) (...)|
La bibliothèque que je développe est censée permettre de gérer des graphismes (ceux de l'interface utilisateur, en fait. Elle doit gérer le système de fenêtrage) de manière générique et donc, portable, histoire de me permettre d'avoir un truc qui me permette si nécessaire de changer de bibliothèque en deux temps trois mouvement pour faire évoluer la future application et de ne pas être obligé de rentrer quantité de #ifdef win32 #elsif ... .
(je vais la commencer avec la SDL, le temps d'avoir un truc fonctionnel, et quand le besoin s'en fera sentir, je pourrais faire évoluer vers des bibliothèques plus poussées en recodant juste quelques fonctions, appartenant à une bibliothèque d'interfaçage)
Vu que la mémoire est quelque chose dont l'utilisation peut enfler très vite dans un jeu (notamment à cause des textures) je préfère avoir une base de classes des plus robustes, et qui, même si elles consomment un peu plus que des pointeurs normaux, me permettent de limiter grandement les problèmes de fuites de mémoire.
J'ai donc, comme on peut le voir dans les messages d'erreur, 1 bibliothèque principale, contenant les mécanismes, mais aucune fonction gérant réellement l'affichage ou la gestion des images, et une bibliothèque d'interfaçage, qui elle, utilise la SDL pour gérer la problématique d'affichage a l'écran, et le chargement/utilisation des textures.
Je teste le tout avec une appli contenant les tests unitaires.
Dans le genre usine a gaz, c'est plutôt pas mal, donc, mais une fois que la base sera implémentée correctement, je n'aurai plus trop de risques de ce côté la, ça me fera un souci de moins à penser quand j'attaquerai le corps de l'appli.
Je pense avoir donné toutes les informations nécessaires? (Sinon, je complèterai si on me demande d'autres détails, naturellement)
PS: le nommage des méthodes et membre n'est pas encore uniforme, je sais, mais je ne sais pas encore exactement comment il sera au final.
Vu que je compte publier cette bibliothèque en LGPL, je pense que je vais m'inspirer des conventions de nommages utilisées par gcc, mais je ne me suis pas encore fixé.
Partager