J'=E9cris une biblioth=E8que de structures de donn=E9es adaptatives,
autrement dit on a une syntaxe de type
// enum type { Dense, Sparse, Fixed, Extensible }
Array t =3D makeArray (Sparse, size)
t=2EgetSize();
et la biblioth=E8que se charge d'utiliser une repr=E9sentation adapt=E9e
aux propri=E9t=E9s demand=E9es.
Pour ce faire, j'utilise une double indirection : pointeur + classe
abstraite.
Cela me permet :
- d'avoir des objets structur=E9s point=E9s (comme en Java)
- de pouvoir utiliser les classes concr=E8tes en cas d'imp=E9ratifs de
performance (ou test)
- de cacher toute la machinerie derri=E8re une interface simple
Le probl=E8me est que lorsque je renvoie des objets de type structur=E9s
d=E9pendants de l'impl=E9mentation concr=E8te (exemple : it=E9rateurs), le
type de l'objet semble perdu et le programme segfaute.
exemple :
int size =3D 5;
ArrayImplementation* ca =3D new ArrayImplementation (size); // classe
concrete
Array a =3D makeArray (Fixed, size); // redirig=E9 vers
ArrayImplementation
ca->getValue (1) // OK
a=2EgetValue (1) // OK
ArrayIterator cit (ca); // classe associ=E9e =E0 l'impl=E9mentation
concrete ArrayImplementation
cit.increment(); // OK
Iterator it =3D a.getIterator() // redirig=E9 vers ArrayIterator
it.increment(); // SEGFAULT
Valgrind incrimine l'indirection due pointeur dans la classe Iterator
class Iterator {
private:
AbstractIteratorI* ptr;
public:
Iterator (AbstractIterator* i) : ptr (i) {}
void increment() {ptr->increment() }; // use of unitialised value of
size 4
}
J'ai l'impression qu'il s'agit d'un probl=E8me de r=E9solution des
virtuelles en raison des multiples couches d'abstraction, mais j'ignore
comment y r=E9m=E9dier.
Voici un code r=E9duit montrant le probl=E8me :
class Iterator;
class AbstractIterator {
public:
virtual bool end () const =3D 0;
virtual int getValue () const =3D 0;
virtual void incr () =3D 0;
};
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Pierre Barbier de Reuille
wrote:
Bonjour,
J'écris une bibliothèque de structures de données adaptatives, autrement dit on a une syntaxe de type
// enum type { Dense, Sparse, Fixed, Extensible } Array t = makeArray (Sparse, size) t.getSize();
et la bibliothèque se charge d'utiliser une représentation adaptée aux propriétés demandées.
Pour ce faire, j'utilise une double indirection : pointeur + classe abstraite. Cela me permet : - d'avoir des objets structurés pointés (comme en Java) - de pouvoir utiliser les classes concrètes en cas d'impératifs de performance (ou test) - de cacher toute la machinerie derrière une interface simple
Le problème est que lorsque je renvoie des objets de type structurés dépendants de l'implémentation concrète (exemple : itérateurs), le type de l'objet semble perdu et le programme segfaute.
[...]
J'ai l'impression qu'il s'agit d'un problème de résolution des virtuelles en raison des multiples couches d'abstraction, mais j'ignore comment y rémédier.
Voici un code réduit montrant le problème :
class Iterator;
class AbstractIterator { public: virtual bool end () const = 0; virtual int getValue () const = 0; virtual void incr () = 0;
manque le destructeur virtuel => problème lors de la désallocation
};
class AbstractArray { public: virtual int getValue (int) const = 0; virtual void setValue (int, int) = 0; virtual Iterator getIterator () = 0; manque le destructeur virtuel => problème lors de la désallocation
int getValue () const { ptr->getValue(); } là aussi
void incr () { ptr->incr(); } };
class Array { private: AbstractArray* ptr; public: Array (AbstractArray* a) : ptr (a) {} int getValue (int i) const { ptr->getValue(i); } manque le return
void setValue (int i, int v) { ptr->setValue (i, v); } Iterator getIterator () { ptr->getIterator(); } ici aussi (d'où probablement la valeur non initialisée)
}; [...]
Diego Olivier
Bon, juste en corrigeant les "return" qui manquent et en rajoutant les destructeurs virtuels ça passe chez moi !
J'écris une bibliothèque de structures de données adaptatives,
autrement dit on a une syntaxe de type
// enum type { Dense, Sparse, Fixed, Extensible }
Array t = makeArray (Sparse, size)
t.getSize();
et la bibliothèque se charge d'utiliser une représentation adaptée
aux propriétés demandées.
Pour ce faire, j'utilise une double indirection : pointeur + classe
abstraite.
Cela me permet :
- d'avoir des objets structurés pointés (comme en Java)
- de pouvoir utiliser les classes concrètes en cas d'impératifs de
performance (ou test)
- de cacher toute la machinerie derrière une interface simple
Le problème est que lorsque je renvoie des objets de type structurés
dépendants de l'implémentation concrète (exemple : itérateurs), le
type de l'objet semble perdu et le programme segfaute.
[...]
J'ai l'impression qu'il s'agit d'un problème de résolution des
virtuelles en raison des multiples couches d'abstraction, mais j'ignore
comment y rémédier.
Voici un code réduit montrant le problème :
class Iterator;
class AbstractIterator {
public:
virtual bool end () const = 0;
virtual int getValue () const = 0;
virtual void incr () = 0;
manque le destructeur virtuel => problème lors de la désallocation
};
class AbstractArray {
public:
virtual int getValue (int) const = 0;
virtual void setValue (int, int) = 0;
virtual Iterator getIterator () = 0;
manque le destructeur virtuel => problème lors de la désallocation
int getValue () const { ptr->getValue(); }
là aussi
void incr () { ptr->incr(); }
};
class Array {
private:
AbstractArray* ptr;
public:
Array (AbstractArray* a) : ptr (a) {}
int getValue (int i) const { ptr->getValue(i); }
manque le return
void setValue (int i, int v) { ptr->setValue (i, v); }
Iterator getIterator () { ptr->getIterator(); }
ici aussi (d'où probablement la valeur non initialisée)
};
[...]
Diego Olivier
Bon, juste en corrigeant les "return" qui manquent et en rajoutant les
destructeurs virtuels ça passe chez moi !
J'écris une bibliothèque de structures de données adaptatives, autrement dit on a une syntaxe de type
// enum type { Dense, Sparse, Fixed, Extensible } Array t = makeArray (Sparse, size) t.getSize();
et la bibliothèque se charge d'utiliser une représentation adaptée aux propriétés demandées.
Pour ce faire, j'utilise une double indirection : pointeur + classe abstraite. Cela me permet : - d'avoir des objets structurés pointés (comme en Java) - de pouvoir utiliser les classes concrètes en cas d'impératifs de performance (ou test) - de cacher toute la machinerie derrière une interface simple
Le problème est que lorsque je renvoie des objets de type structurés dépendants de l'implémentation concrète (exemple : itérateurs), le type de l'objet semble perdu et le programme segfaute.
[...]
J'ai l'impression qu'il s'agit d'un problème de résolution des virtuelles en raison des multiples couches d'abstraction, mais j'ignore comment y rémédier.
Voici un code réduit montrant le problème :
class Iterator;
class AbstractIterator { public: virtual bool end () const = 0; virtual int getValue () const = 0; virtual void incr () = 0;
manque le destructeur virtuel => problème lors de la désallocation
};
class AbstractArray { public: virtual int getValue (int) const = 0; virtual void setValue (int, int) = 0; virtual Iterator getIterator () = 0; manque le destructeur virtuel => problème lors de la désallocation
int getValue () const { ptr->getValue(); } là aussi
void incr () { ptr->incr(); } };
class Array { private: AbstractArray* ptr; public: Array (AbstractArray* a) : ptr (a) {} int getValue (int i) const { ptr->getValue(i); } manque le return
void setValue (int i, int v) { ptr->setValue (i, v); } Iterator getIterator () { ptr->getIterator(); } ici aussi (d'où probablement la valeur non initialisée)
}; [...]
Diego Olivier
Bon, juste en corrigeant les "return" qui manquent et en rajoutant les destructeurs virtuels ça passe chez moi !