Gestion de memoire automatique en c++

Soyez le premier à donner votre avis sur cette source.

Snippet vu 5 083 fois - Téléchargée 15 fois

Contenu du snippet

ce source peut etre utiliser en gestion de memoire automatiquement
il faut utiliser la class IObject comme une class mere et la template GsMem
en peut utiliser le Macro suivant pour simplifier les chose

#define SET_AUTO_MEM(name) typedef GsMem<name> name#$;

Source / Exemple :


// le fichier de base
// base.h
#include <stdio.h>

class IObject {
public:
int count;
Object() : count(0) {}
virtual ~Object() {}
friend int addRef(IObject * obj);
friend int release(IObject * obj);
};

int addRef(IObject * obj) {
if(obj==0) return 0;
return obj->count++;
}

int release(IObject * obj){
if (obj==0) return 0;
obj->count--;
if(obj->count<=0){
delete obj;
return 0;
}
return obj->count ;
}

template <class T>
class GsMem {
public:
T * obj ;
GsMem(T * oobj) {
if(oobj){
   obj = oobj;
   addRef(obj);
}
obj = 0;
}

virtual ~GsMem() {
release(obj);
}

GsMem & operator=(IObject * oobj) {
if(oobj) {
   if (obj) {
       release(obj);
       obj = oobj ;
       addRef(obj);
   }
   else {
       obj = oobj ;
       addRef(obj);
   }
else {
   if(release(obj)<=0) obj=0;
}
}

};

// fichier .cpp

#include "base.h"

class Test : public IObject {
public:
    int cd ;
    Test(int code) {
        cd = code ;
        printf("creation de l'objet %d\n",code);
    }
    virtual ~Test() {
        printf("destruction de l'objet %d\n",cd);
    }

};

int main() {
     printf("exemple 1 : (sans utilisation du GsMem)\n");
    {
         Test * t = new Test(1) ;
    }
    printf("exemple 2 : (utilisation du GsMem au declaration)\n");
    {
         GsMem<Test> t = new Test(2) ;
    }

    printf("exemple 3 : (utilisation du GsMem )\n");
    {
         Test * t = new Test(3) ;
         GsMem<Test> gs = t ;
    }

   return 0 ;
 
}

Conclusion :


affichage:

exemple 1 : (sans utilisation du GsMem)
creation de l'objet 1
exemple 2 : (utilisation du GsMem au declaration)
creation de l'objet 2
destruction de l'objet 2
exemple 3 : (utilisation du GsMem )
creation de l'objet 3
destruction de l'objet 3

A voir également

Ajouter un commentaire

Commentaires

On retrouve ici COM de Microsoft avec l'interface IUnknown (au lieu de IObject) avec les smart pointers associés.
C'est mieux que les auto_ptr d'origine du C++ mais en deça de boost.
cptpingu
Messages postés
3834
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
10 juin 2019
85 -
>> que peut tu me dit si je mis " class Test : public virtual IObject {... "
Comprends-tu à quoi sert le mot clé "virtual" ? Je n'en ai pas l'impression...
Un héritage virtuel ("public virtual") n'est surtout utile qu'en cas d'héritage multiple en diamand, pour ne garder "qu'une partie de la branche" C'est une notion avancée, peu utilisé.

Je critiquais la simple présence d'héritage dynamique, qui n'a rien à faire dans ce genre de code...
merci de tes remarques.
que peut tu me dit si je mis " class Test : public virtual IObject {... "
cptpingu
Messages postés
3834
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
10 juin 2019
85 -
Bonjour.

Je déconseille fortement l'utilisation de cette source ! Je la laisse à titre d'exemple.
Il y a plusieurs soucis:

Techniquement:
- Le mot clé "friend" est à éviter. C'est généralement signe d'une mauvaise conception. Ici on aurait pu largement s'en passer, au profit de deux méthodes statiques. (voir même comme de simples méthodes membres, vu ce que tu en fais).
- Plutôt que de faire: "if (obj==0) return 0;", lever une assertion aurait été bien plus judicieux. Ici tu masques une erreur.
- L'obligation de devoir hériter d'une classe, force la création d'une vtable juste pour cela. Or, niveau performance, ce n'est pas forcément terrible. Utiliser des templates aurait permis d'avoir ce genre de fonctionnalité, sans l'obligation du coût caché par un polymorphisme (dès le moment ou tu as un seul virtual, tu auras une table virtuelle...)
- On différencie une variable locale d'un attribut via un signe distinctif. On utilise généralement "_". On devrait donc avoir: T* obj => T* _obj;

Architecture:
L'architecture n'est pas terrible. Utiliser la classe "IObject" seule, conduit à des fuites de mémoires. Normalement, une seule classe devrait suffire.
Soit tu fais une classe "intrusive", comme les "boost::intrusive_ptr", auquel cas ta classe hérite (de préférence statiquement) d'un compteur partagé entre les différentes instances du même type, soit tu donnes l'intégralité de la réponsabilité à une classe dédiée (comme les std::shared_ptr). Avoir deux classes qui ont chacunes une partie de la reponsabilité est vraiment peu élégant et source d'erreurs.

Principe:
Sur le principe, tu as essayé de refaire en (beaucoup) moins bien, un système de smart pointer. Je conseille à ceux qui liront de plutôt utiliser:
- boost::intrusive_ptr
- boost::shared_ptr ou std::shared_ptr
- boost::weak_ptr ou std::weak_ptr
- std::unique_ptr
alfrai
Messages postés
69
Date d'inscription
mardi 11 avril 2006
Statut
Membre
Dernière intervention
23 juillet 2013
-
Merci pour la source !

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.