Hmm ok je vois (pour la première partie en tous cas). Ca correspond probablement à ce que je m'étais amusé à implémenter :
template<class T>
class ref {
T *ptr;
unsigned *counter;
void incref() { if (counter) (*counter)++; }
void decref() { if (counter && --(*counter) == 0) delete ptr, delete counter; }
public:
ref() : ptr(0), counter(0) {}
ref(const ref<T> &ref) : ptr(ref.ptr), counter(ref.counter) { incref(); }
ref(T *ptr) : ptr(ptr) { counter = ptr ? new unsigned(1) : 0; }
~ref() { decref(); }
ref<T> &operator = (const ref &ref) {
// Using the same logic may free the original object if counter = 1
if (ref.ptr == ptr)
return *this;
// Else, do the equivalent of destructing "this" and constructing with "ref"
decref();
ptr = ref.ptr, counter = ref.counter;
incref();
return *this;
}
ref<T> &operator = (T *newPtr) {
decref();
counter = (ptr = newPtr) ? new unsigned(1) : 0;
return *this;
}
operator T* () const { return ptr; }
T* operator -> () const { return ptr; }
T& operator * () const { return *ptr; }
bool operator == (const ref<T> &ref) const { return ref.ptr == ptr; }
bool operator != (const ref<T> &ref) const { return ref.ptr != ptr; }
};
Alors on n'a qu'à utiliser ref<Objet> à la place de Objet * pour une gestion automatique de la mémoire, et utiliser le modèle standard au besoin

class Image {
const char *name;
public:
Image(const char *name) : name(name) { cout << "Constructed " << name << endl; }
~Image() { cout << "Destructed " << name << endl; }
int getWidth() { return 42; }
};
ref<Image> g_image = new Image("1.png");
void method(Image *myImage) {
cout << "Size is " << myImage->getWidth() << endl;
}
int main(int argc, const char * argv[]) {
ref<Image> local;
g_image = NULL; /* libération explicite */
local = new Image("3.png"); /* affectation possible depuis un pointeur */
method(local); /* passage à une fonction d'API n'utilisant pas ref<> */
cout << "Locally: " << local->getWidth() << endl; /* Utilisation de ref<Image> comme une Image* */
return 0;
}
png
=> Constructed 1.png
Destructed 1.png
Constructed 2.png
Size is 42
Locally: 42
Destructed 2.
Je pense que je vais choisir ça en fin de compte, ça me paraît assez facile à comprendre (juste dire aux débutants que s'ils veulent s'affranchir de la gestion de la mémoire ils n'ont qu'à utiliser ref<Truc> plutôt que Truc*) et comme ça marche pour tout sans polluer ceux qui ne veulent pas s'en servir, ça me paraît être un bon compromis.
