 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Cyrille cns Szymanski Guest
|
Posted: Sun Aug 17, 2003 11:07 pm Post subject: realloc et templates |
|
|
Bonjour,
Je voudrais créer un tableau d'objets (définis dans une template) de
taille variable. Il n'y a pas d'opérateur renew[], je me suis donc
rabattu sur realloc() et c'est ce qui est délicat.
Le problème est d'appeler correctement les constructeurs. Bizarrement
(pour moi), le code fonctionne pour les destructeurs mais pas les
constructeurs.
Voici une partie du code :
template <class Obj>
struct cnsBuffer
{
Obj *m_ptr; // le tableau d'objets
unsigned int m_nb; // la taille du tableau
int allocate( unsigned int nb )
{
FATAL( nb!=0 );
int ret=-1;
if( nb<m_nb )
{
// détruire les objets supprimés
for( unsigned int i=nb; i
{
// ce bout de code fonctionne très bien
m_ptr[i].~Obj();
}
}
m_ptr = (Obj*)realloc( m_ptr, nb*sizeof(Obj) );
if( m_ptr!=0 )
{
// initialiser les nouveaux objets
for( unsigned int i=m_nb; i
{
// celui là pose problème
m_ptr[i].Obj();
}
m_nb = nb;
ret = 0;
}
else
{
m_nb = 0;
ret = -1;
}
return ret;
}
};
Avec Borland C++ 5.5 j'obtiens l'erreur que dans l'expression "m_ptr
[i].Obj();" :
Structure required on left side of . or .* in function cnsBuffer
-> évidemment avec un char cela n'a pas de sens
'Obj' is not a member of 'TestClass' in function cnsBuffer
<TestClass>::allocate(unsigned int)
-> cette erreur me laisse perplexe, pourquoi le mécanisme de template ne
l'a pas traduit en TestClass() ?
En fait ma question est comment faire (proprement) ce que je cherche à
faire ?
J'ai aussi pensé à allouer un tableau temporaire avec new[] (dans le cas
où la taille augmente) puis le recopier dans la zone allouée par realloc
() et enfin le libérer avec free() pour ne pas appeler de destructeur,
mais c'est plutôt moche.
Merci d'avance pour votre aide,
--
_|_|_| CnS
_|_| for(n=0;b;n++)
_| b&=b-1; /*pp.47 K&R*/
|
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Mon Aug 18, 2003 1:28 pm Post subject: Re: realloc et templates |
|
|
On 18 Aug 2003 12:52:11 GMT, "Cyrille "cns" Szymanski"
<cns2 (AT) cns (DOT) invalid> wrote:
| Quote: | D'après ce que j'ai compris, il faut aussi doter la classe Obj de
l'opérateur
void *operator new(size_t s, Obj *a)
|
Ah ? T'es sûr ? Va falloir que je vérifie, mais je ne vois pas
pourquoi ça serait obligatoire.
| Quote: | Franchement je ne vois pas pourquoi "m_ptr[i].~Obj();" fonctionne et pas
"m_ptr[i].Obj();".
|
"m_ptr[i].~Obj();" a un sens, puisque m_ptr[i] est un objet de classe
Obj, construit précédemment.
Par contre, quand tu écris "m_ptr[i].Obj();", m_ptr[i] n'est pas
encore un objet de classe Obj -- je vois mal comment ça pourrait avoir
un sens. Mais bon, a priori je me trompe quelque part -- je n'ai
jamais réussi à comprendre le fonctionnement des appels "directs" aux
constructeurs/destructeurs.
--
Tout sur fr.* (FAQ, etc.) : http://www.usenet-fr.net/fur/
et http://www.aminautes.org/forums/serveurs/tablefr.html
Archives : http://groups.google.com/advanced_group_search
http://www.usenet-fr.net/fur/usenet/repondre-sur-usenet.html
|
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
|
| Back to top |
|
 |
Patrick Mézard Guest
|
Posted: Mon Aug 18, 2003 6:13 pm Post subject: Re: realloc et templates |
|
|
| Quote: | Je voudrais créer un tableau d'objets (définis dans une template) de
taille variable. Il n'y a pas d'opérateur renew[], je me suis donc
rabattu sur realloc() et c'est ce qui est délicat.
Le problème est d'appeler correctement les constructeurs. Bizarrement
(pour moi), le code fonctionne pour les destructeurs mais pas les
constructeurs.
|
Tu peux jeter un coup d'oeil aux fonctions template std::unitialized_fill et
std::uninitialized_fill_n qui sont déclarées dans <memory>. A priori, ça
fait exactement ce que tu veux. Un peu de documentation à ce sujet :
http://www.sgi.com/tech/stl/uninitialized_fill.html
http://www.sgi.com/tech/stl/uninitialized_fill_n.html
Peut-être que l'implémentation fournie par Borland résoudra tes problèmes.
En plus, ça donne de bonnes garanties en cas de lancé d'exception lors de la
construction. Ce qui est un peu bizarre c'est qu'ils ne fournissent pas des
algorithmes similaires pour appeler les destructeurs.
Patrick Mézard
|
|
| Back to top |
|
 |
Patrick Mézard Guest
|
Posted: Tue Aug 19, 2003 6:44 am Post subject: Re: realloc et templates |
|
|
| Quote: | Merci beaucoup pour ces infos. J'ai regardé l'implémentation de SGI et
j'en ai extrait quelques bouts intéressants. La doc SGI donne un exemple
d'utilisation de construct() qui est la base de cet algorithme.
Malheureusement il ne fonctionne pas sous Borland C++ 5.5. Le compilo
réclame un 'operator new(unsigned int,void *)'
|
D'après la documentation de SGI, "construct" est obsolète. L'idée c'était
plutôt de te servir des implémentations fournies par Borland (enfin
j'espère) dans <memory>. L'intérêt est que si jamais ces fonctions existent,
les #include nécessaires seront faits au niveau de <memory>.
Je pense à ça, parce que sous MSVC6 par exemple, il est nécessaire de faire
un #include <new> pour avoir des constructeurs des placement. Inspire toi
des headers de Borland, plutôt que du code de SGI, ils sont adaptés à ton
compilateur.
Patrick Mézard
|
|
| Back to top |
|
 |
Cyrille cns Szymanski Guest
|
Posted: Tue Aug 19, 2003 11:28 am Post subject: Re: realloc et templates |
|
|
| Quote: | Je pense à ça, parce que sous MSVC6 par exemple, il est nécessaire de
faire un #include <new> pour avoir des constructeurs des placement.
|
Oui, c'est exactement ce qui me manquait. Dans mon cas et avec Borland, il
faut juste définir un extern new pour que ça marche.
extern void * operator new(size_t size, void* ptr);
La question que je me pose est de savoir pourquoi ? Est-ce pour permettre à
l'utilisateur de fournir son propre new ?
--
_|_|_| CnS
_|_| for(n=0;b;n++)
_| b&=b-1; /*pp.47 K&R*/
|
|
| Back to top |
|
 |
Gabriel Dos Reis Guest
|
Posted: Tue Aug 19, 2003 11:59 am Post subject: Re: realloc et templates |
|
|
"Cyrille "cns" Szymanski" <cns2 (AT) cns (DOT) invalid> writes:
| Quote: | La question que je me pose est de savoir pourquoi ?
|
es-tu sûr de vouloir savoir ?
-- Gaby
|
|
| Back to top |
|
 |
Gabriel Dos Reis Guest
|
Posted: Tue Aug 19, 2003 3:31 pm Post subject: Re: realloc et templates |
|
|
"Cyrille "cns" Szymanski" <cns2 (AT) cns (DOT) invalid> writes:
| Quote: | | La question que je me pose est de savoir pourquoi ?
es-tu sûr de vouloir savoir ?
J'ai dû dire quelquechose qui t'a fâché, non ?
|
Non. Aucunément. C'était ma façon de dire que si tu ne maîtrises pas
encore les fonctionnalités simples (je ne considère pas la gestion de
mémoire ainsi que la « magie » derrière new/delete comme simple)
alors, tu seras probablement confus par une explication detaillée du
pourquoi et comment du new. D'ailleurs ce que j'ai dit était très
sommaire et j'ai escamoté beaucoup de détails.
-- Gaby
|
|
| Back to top |
|
 |
drkm Guest
|
Posted: Mon Aug 25, 2003 6:47 am Post subject: Re: realloc et templates |
|
|
Fabien LE LEZ <gramster (AT) gramster (DOT) com> writes:
| Quote: | Il faut utiliser le new de position (placement new). De mémoire (je
l'utilise peu), il faut faire :
new (m_ptr[i]) Obj;
|
Ne serait-ce pas plutôt :
new ( & m_ptr[i] ) Obj ;
ou, au choix :
new ( m_ptr + i ) Obj ;
Il me semble que le placement new demande une adresse, et non une
référence.
--drkm
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|