"Olivier" a écrit dans le message de
news:3f2b9187$0$10532$Tout d'abord merci de vos precieux conseil
je suis un autodidacte qui souffre avec la STL dur dur
_pCoArt est devenu _pArtList
voici le nouveau code dans la classe collection TCoArticle
std::vector<TArticle*>::const_iterator
TCoArticles::SearchArticle(TArticle & Art)
^^^^^^^^^^ ^^^^^^
{
return std::find(_pArtList.begin(),_pArtList.end(),&Art);
}
La suppression :
bool __fastcall TCoArticles::DeleteArticle(TArticle& Art)}
^^^^^^^^^
{
bool bResúlse;
std::vector<TArticle*>::const_iterator i;
i= SearchArticle(Art);
if(i){
SearchArticle renvoie maintenant un itérateur. Pour tester si
l'élément a été trouvé ou non, utilises plutôt :
if( i != _pArtList.end() )
_pArtList.erase( _pArtList.begin()+ (i -_pArtList.end())) ;
Puisque i est maintenant un itérateur, tu peux faire :
_pArtList.erase( i );
Par ailleurs, je te conseille de le renommer en "it" plutôt que "i"
(qui laisse penser que c'est un indice)...
delete *i; // violation pourquoi ??? que le mette avant ou apres le errse
Peut-être que tu rentres dans le bloc même quand l'élément a été
trouvé (voir plus haut), ce qui fait que tu tentes d'effacer un
élément via un itérateur invalide.
}else{
bResúlse;
}
Si tu mets à false quand l'élément n'a pas été trouvé, il faut mettre
à true quand il l'a été. Par ailleurs, tu peux te passer completement
de cette clause else vu que tu initialises à false au début de ta
fonction...
"Olivier" <osarda@free.fr> a écrit dans le message de
news:3f2b9187$0$10532$626a54ce@news.free.fr...
Tout d'abord merci de vos precieux conseil
je suis un autodidacte qui souffre avec la STL dur dur
_pCoArt est devenu _pArtList
voici le nouveau code dans la classe collection TCoArticle
std::vector<TArticle*>::const_iterator
TCoArticles::SearchArticle(TArticle & Art)
^^^^^^^^^^ ^^^^^^
{
return std::find(_pArtList.begin(),_pArtList.end(),&Art);
}
La suppression :
bool __fastcall TCoArticles::DeleteArticle(TArticle& Art)}
^^^^^^^^^
{
bool bResúlse;
std::vector<TArticle*>::const_iterator i;
i= SearchArticle(Art);
if(i){
SearchArticle renvoie maintenant un itérateur. Pour tester si
l'élément a été trouvé ou non, utilises plutôt :
if( i != _pArtList.end() )
_pArtList.erase( _pArtList.begin()+ (i -_pArtList.end())) ;
Puisque i est maintenant un itérateur, tu peux faire :
_pArtList.erase( i );
Par ailleurs, je te conseille de le renommer en "it" plutôt que "i"
(qui laisse penser que c'est un indice)...
delete *i; // violation pourquoi ??? que le mette avant ou apres le errse
Peut-être que tu rentres dans le bloc même quand l'élément a été
trouvé (voir plus haut), ce qui fait que tu tentes d'effacer un
élément via un itérateur invalide.
}else{
bResúlse;
}
Si tu mets à false quand l'élément n'a pas été trouvé, il faut mettre
à true quand il l'a été. Par ailleurs, tu peux te passer completement
de cette clause else vu que tu initialises à false au début de ta
fonction...
"Olivier" a écrit dans le message de
news:3f2b9187$0$10532$Tout d'abord merci de vos precieux conseil
je suis un autodidacte qui souffre avec la STL dur dur
_pCoArt est devenu _pArtList
voici le nouveau code dans la classe collection TCoArticle
std::vector<TArticle*>::const_iterator
TCoArticles::SearchArticle(TArticle & Art)
^^^^^^^^^^ ^^^^^^
{
return std::find(_pArtList.begin(),_pArtList.end(),&Art);
}
La suppression :
bool __fastcall TCoArticles::DeleteArticle(TArticle& Art)}
^^^^^^^^^
{
bool bResúlse;
std::vector<TArticle*>::const_iterator i;
i= SearchArticle(Art);
if(i){
SearchArticle renvoie maintenant un itérateur. Pour tester si
l'élément a été trouvé ou non, utilises plutôt :
if( i != _pArtList.end() )
_pArtList.erase( _pArtList.begin()+ (i -_pArtList.end())) ;
Puisque i est maintenant un itérateur, tu peux faire :
_pArtList.erase( i );
Par ailleurs, je te conseille de le renommer en "it" plutôt que "i"
(qui laisse penser que c'est un indice)...
delete *i; // violation pourquoi ??? que le mette avant ou apres le errse
Peut-être que tu rentres dans le bloc même quand l'élément a été
trouvé (voir plus haut), ce qui fait que tu tentes d'effacer un
élément via un itérateur invalide.
}else{
bResúlse;
}
Si tu mets à false quand l'élément n'a pas été trouvé, il faut mettre
à true quand il l'a été. Par ailleurs, tu peux te passer completement
de cette clause else vu que tu initialises à false au début de ta
fonction...
"Olivier" wrote in
news:3f2cddaf$0$27407$:Projet fait sur Borland C++Builder 6 et Windows 98 code guard active
option de complition standard faut il changer une option ? autre
precison outil UML utilise ClassBuilder 2.4 gratuit generation du
squellette des classes uniquement
Il a fait des progrès cet outil ? Dans le passé, son mainteneur ne
voulait pas supporter la STL et imposait à la place ses propres
conteneurs.
bool TCoArticles::DeleteArticle(TArticle& Art)
bool TCoArticles::DeleteArticle(const TArticle& Art){
bool bResúlse;
if (Count()>0){ // size()
std::vector<TArticle*>::const_iterator it=NULL;
it= SearchArticle(Art);
std::vector<TArticle*>::iterator it > std::find_if(_pArtList.begin(),_pArtList.end(),
std::bind2nd( IsEqualPointedTo<TArticle>(), &Art));// if(it!=_pArtList.end()){ // ce test ne marche pas il le
saute // par contre si je fait
Si il le saute, ça veut dire qu'il n'a rien trouvé.
D'autant que c'est le seul et unique test valide à faire. "if (it)"
n'a pas de sens. it est un iterateur, pas un pointeur. Déjà
l'initialiser à NULL (ou même 0) n'a pas de sens. [bon d'accord, ici
il est implémenté 99% du temps comme un pointeur ; mais ce servir de
cet aspect d'implémentation est sémantiquement faux]
if(it){ // ce test passe mais sur delete *it j'ai une violation
d'acces
_pArtList.erase( _pArtList.begin()+ (it -_pArtList.end())) ;
_pArtList.erase(it); // tout simplementdelete *it;
bRes=true;
}
}
Le problème est que ton Article n'a pas été trouvé car tu faisais une
recherche sur des pointeurs d'articles et pas des articles. Cf. juste
après pour ce qui te manque.file://----------------------------------------------------------------
-----
----------------------------------------------------------------------
Autre question ai je les bon header ?
#include <vector>
#include <iterator>
#include <algorithm>
#include <functional>
A priori, tu n'as pas besoin ici de <iterator>; mais bien de
<functional> car il te faut rajouter ce qui suit pour pouvoir comparer
des articles ensembles (et pas des adresses d'articles) :
template< typename T >
struct IsEqualPointedTo
: std::binary_function<const T*, const T*, bool>
// James, tu avais oublié l'héritage avec binary_function ;)
{
bool operator()( T const* lhs, T const* rhs ) const {
return *lhs == *rhs ;
}
} ;
bool TArticle::operator==(const TArticle &a) const {
return Categorie_==a.Categorie_ && Description_==a.Description_
&& NomArt_==a.NomArt_;
// Rem: j'ai ignoré le prix ici
}file://----------------------------------------------------------------
----- ----------------------------------------------------------------
Si je fait _pArtList.erase(it)
bcb=>
[C++ Erreur] CoArticles.cpp(123): E2285 Impossible de trouver une
correspondance pour '_STL::vector<TArticle *,_STL::allocator<TArticle
*>::erase(TArticle * const *)'
Le selecteur de fonction attend pArtList.erase(TArticle **__position)
ou pArtList.erase(TArticle
**__first,TArticle **__Last)
ou est l'erreur ?
Enlève le const_ de const_iterator
"Olivier" <osarda@free.fr> wrote in
news:3f2cddaf$0$27407$626a54ce@news.free.fr:
Projet fait sur Borland C++Builder 6 et Windows 98 code guard active
option de complition standard faut il changer une option ? autre
precison outil UML utilise ClassBuilder 2.4 gratuit generation du
squellette des classes uniquement
Il a fait des progrès cet outil ? Dans le passé, son mainteneur ne
voulait pas supporter la STL et imposait à la place ses propres
conteneurs.
bool TCoArticles::DeleteArticle(TArticle& Art)
bool TCoArticles::DeleteArticle(const TArticle& Art)
{
bool bResúlse;
if (Count()>0){ // size()
std::vector<TArticle*>::const_iterator it=NULL;
it= SearchArticle(Art);
std::vector<TArticle*>::iterator it > std::find_if(_pArtList.begin(),_pArtList.end(),
std::bind2nd( IsEqualPointedTo<TArticle>(), &Art));
// if(it!=_pArtList.end()){ // ce test ne marche pas il le
saute // par contre si je fait
Si il le saute, ça veut dire qu'il n'a rien trouvé.
D'autant que c'est le seul et unique test valide à faire. "if (it)"
n'a pas de sens. it est un iterateur, pas un pointeur. Déjà
l'initialiser à NULL (ou même 0) n'a pas de sens. [bon d'accord, ici
il est implémenté 99% du temps comme un pointeur ; mais ce servir de
cet aspect d'implémentation est sémantiquement faux]
if(it){ // ce test passe mais sur delete *it j'ai une violation
d'acces
_pArtList.erase( _pArtList.begin()+ (it -_pArtList.end())) ;
_pArtList.erase(it); // tout simplement
delete *it;
bRes=true;
}
}
Le problème est que ton Article n'a pas été trouvé car tu faisais une
recherche sur des pointeurs d'articles et pas des articles. Cf. juste
après pour ce qui te manque.
file://----------------------------------------------------------------
-----
----------------------------------------------------------------------
Autre question ai je les bon header ?
#include <vector>
#include <iterator>
#include <algorithm>
#include <functional>
A priori, tu n'as pas besoin ici de <iterator>; mais bien de
<functional> car il te faut rajouter ce qui suit pour pouvoir comparer
des articles ensembles (et pas des adresses d'articles) :
template< typename T >
struct IsEqualPointedTo
: std::binary_function<const T*, const T*, bool>
// James, tu avais oublié l'héritage avec binary_function ;)
{
bool operator()( T const* lhs, T const* rhs ) const {
return *lhs == *rhs ;
}
} ;
bool TArticle::operator==(const TArticle &a) const {
return Categorie_==a.Categorie_ && Description_==a.Description_
&& NomArt_==a.NomArt_;
// Rem: j'ai ignoré le prix ici
}
file://----------------------------------------------------------------
----- ----------------------------------------------------------------
Si je fait _pArtList.erase(it)
bcb=>
[C++ Erreur] CoArticles.cpp(123): E2285 Impossible de trouver une
correspondance pour '_STL::vector<TArticle *,_STL::allocator<TArticle
*>
::erase(TArticle * const *)'
Le selecteur de fonction attend pArtList.erase(TArticle **__position)
ou pArtList.erase(TArticle
**__first,TArticle **__Last)
ou est l'erreur ?
Enlève le const_ de const_iterator
"Olivier" wrote in
news:3f2cddaf$0$27407$:Projet fait sur Borland C++Builder 6 et Windows 98 code guard active
option de complition standard faut il changer une option ? autre
precison outil UML utilise ClassBuilder 2.4 gratuit generation du
squellette des classes uniquement
Il a fait des progrès cet outil ? Dans le passé, son mainteneur ne
voulait pas supporter la STL et imposait à la place ses propres
conteneurs.
bool TCoArticles::DeleteArticle(TArticle& Art)
bool TCoArticles::DeleteArticle(const TArticle& Art){
bool bResúlse;
if (Count()>0){ // size()
std::vector<TArticle*>::const_iterator it=NULL;
it= SearchArticle(Art);
std::vector<TArticle*>::iterator it > std::find_if(_pArtList.begin(),_pArtList.end(),
std::bind2nd( IsEqualPointedTo<TArticle>(), &Art));// if(it!=_pArtList.end()){ // ce test ne marche pas il le
saute // par contre si je fait
Si il le saute, ça veut dire qu'il n'a rien trouvé.
D'autant que c'est le seul et unique test valide à faire. "if (it)"
n'a pas de sens. it est un iterateur, pas un pointeur. Déjà
l'initialiser à NULL (ou même 0) n'a pas de sens. [bon d'accord, ici
il est implémenté 99% du temps comme un pointeur ; mais ce servir de
cet aspect d'implémentation est sémantiquement faux]
if(it){ // ce test passe mais sur delete *it j'ai une violation
d'acces
_pArtList.erase( _pArtList.begin()+ (it -_pArtList.end())) ;
_pArtList.erase(it); // tout simplementdelete *it;
bRes=true;
}
}
Le problème est que ton Article n'a pas été trouvé car tu faisais une
recherche sur des pointeurs d'articles et pas des articles. Cf. juste
après pour ce qui te manque.file://----------------------------------------------------------------
-----
----------------------------------------------------------------------
Autre question ai je les bon header ?
#include <vector>
#include <iterator>
#include <algorithm>
#include <functional>
A priori, tu n'as pas besoin ici de <iterator>; mais bien de
<functional> car il te faut rajouter ce qui suit pour pouvoir comparer
des articles ensembles (et pas des adresses d'articles) :
template< typename T >
struct IsEqualPointedTo
: std::binary_function<const T*, const T*, bool>
// James, tu avais oublié l'héritage avec binary_function ;)
{
bool operator()( T const* lhs, T const* rhs ) const {
return *lhs == *rhs ;
}
} ;
bool TArticle::operator==(const TArticle &a) const {
return Categorie_==a.Categorie_ && Description_==a.Description_
&& NomArt_==a.NomArt_;
// Rem: j'ai ignoré le prix ici
}file://----------------------------------------------------------------
----- ----------------------------------------------------------------
Si je fait _pArtList.erase(it)
bcb=>
[C++ Erreur] CoArticles.cpp(123): E2285 Impossible de trouver une
correspondance pour '_STL::vector<TArticle *,_STL::allocator<TArticle
*>::erase(TArticle * const *)'
Le selecteur de fonction attend pArtList.erase(TArticle **__position)
ou pArtList.erase(TArticle
**__first,TArticle **__Last)
ou est l'erreur ?
Enlève le const_ de const_iterator
writes:
| Gabriel Dos Reis wrote in message
| news:...
| > writes:
| [...]
| > | Je ne vois qu'un problème. Problème que je crois n'apparaît pas
| > | dans le code réel, mais que la norme permet. Si on fait dépendre
| > | la façon que le paramètre est passé de ce que le constructeur de
| > | copie soit inline ou non, il y a une risque qu'il soit inline où
| > | la fonction est appelée, et non inline où la fonction est
| > | définie.
| > C'est une violation des presciptions explicites sur ce que doit
| > être une fonction inline.
| > 7.1.2/4
| > An inline function shall be defined in every translation unit in
| > which it is used
| Exact. Le point de mon exemple, c'est que les constructeurs de la
| classe ne servent pas dans l'unité de traduction où est définie la
| fonction appelée.
il faut lire le paragraphe en entier,
| > and shall have exactly the same definition in every case
| > (3.2). [Note: a call to the inline function may be encountered
| > before its defi-nition appears in the translation unit. ] If a
| > function with external linkage is declared inline in one
| > transla-tion unit, it shall be declared inline in all translation
| > units in which it appears; no diagnostic is required. An inline
| > function with external linkage shall have the same address in all
| > translation units. [...]
| > [...]
| > | Je crois que de tel code est légal.
| > Non, le code n'est pas valide.
| Je crois que si.
Non, il ne l'est pas parce que la norme requiert
If a function with external linkage is declared inline in one
translation unit, *it shall be declared inline in all translation
units in which it appears*; no diagnostic is required.
En particulier dans f.cc, le constructeur de copie est déclaré inline
alors dans dans g.cc, elle ne l'est pas. C'est bien une violation des
dispositions de la norme et le paragraphe que je cite s'applique bien.
[...]
| C'est évidemment un cas qui ne se présente pas dans la pratique.
| Mais
C'est évidemment un cas bugué qui a ce qu'il mérite.
kanze@gabi-soft.fr writes:
| Gabriel Dos Reis <gdr@integrable-solutions.net> wrote in message
| news:<m3r841snod.fsf@uniton.integrable-solutions.net>...
| > kanze@gabi-soft.fr writes:
| [...]
| > | Je ne vois qu'un problème. Problème que je crois n'apparaît pas
| > | dans le code réel, mais que la norme permet. Si on fait dépendre
| > | la façon que le paramètre est passé de ce que le constructeur de
| > | copie soit inline ou non, il y a une risque qu'il soit inline où
| > | la fonction est appelée, et non inline où la fonction est
| > | définie.
| > C'est une violation des presciptions explicites sur ce que doit
| > être une fonction inline.
| > 7.1.2/4
| > An inline function shall be defined in every translation unit in
| > which it is used
| Exact. Le point de mon exemple, c'est que les constructeurs de la
| classe ne servent pas dans l'unité de traduction où est définie la
| fonction appelée.
il faut lire le paragraphe en entier,
| > and shall have exactly the same definition in every case
| > (3.2). [Note: a call to the inline function may be encountered
| > before its defi-nition appears in the translation unit. ] If a
| > function with external linkage is declared inline in one
| > transla-tion unit, it shall be declared inline in all translation
| > units in which it appears; no diagnostic is required. An inline
| > function with external linkage shall have the same address in all
| > translation units. [...]
| > [...]
| > | Je crois que de tel code est légal.
| > Non, le code n'est pas valide.
| Je crois que si.
Non, il ne l'est pas parce que la norme requiert
If a function with external linkage is declared inline in one
translation unit, *it shall be declared inline in all translation
units in which it appears*; no diagnostic is required.
En particulier dans f.cc, le constructeur de copie est déclaré inline
alors dans dans g.cc, elle ne l'est pas. C'est bien une violation des
dispositions de la norme et le paragraphe que je cite s'applique bien.
[...]
| C'est évidemment un cas qui ne se présente pas dans la pratique.
| Mais
C'est évidemment un cas bugué qui a ce qu'il mérite.
writes:
| Gabriel Dos Reis wrote in message
| news:...
| > writes:
| [...]
| > | Je ne vois qu'un problème. Problème que je crois n'apparaît pas
| > | dans le code réel, mais que la norme permet. Si on fait dépendre
| > | la façon que le paramètre est passé de ce que le constructeur de
| > | copie soit inline ou non, il y a une risque qu'il soit inline où
| > | la fonction est appelée, et non inline où la fonction est
| > | définie.
| > C'est une violation des presciptions explicites sur ce que doit
| > être une fonction inline.
| > 7.1.2/4
| > An inline function shall be defined in every translation unit in
| > which it is used
| Exact. Le point de mon exemple, c'est que les constructeurs de la
| classe ne servent pas dans l'unité de traduction où est définie la
| fonction appelée.
il faut lire le paragraphe en entier,
| > and shall have exactly the same definition in every case
| > (3.2). [Note: a call to the inline function may be encountered
| > before its defi-nition appears in the translation unit. ] If a
| > function with external linkage is declared inline in one
| > transla-tion unit, it shall be declared inline in all translation
| > units in which it appears; no diagnostic is required. An inline
| > function with external linkage shall have the same address in all
| > translation units. [...]
| > [...]
| > | Je crois que de tel code est légal.
| > Non, le code n'est pas valide.
| Je crois que si.
Non, il ne l'est pas parce que la norme requiert
If a function with external linkage is declared inline in one
translation unit, *it shall be declared inline in all translation
units in which it appears*; no diagnostic is required.
En particulier dans f.cc, le constructeur de copie est déclaré inline
alors dans dans g.cc, elle ne l'est pas. C'est bien une violation des
dispositions de la norme et le paragraphe que je cite s'applique bien.
[...]
| C'est évidemment un cas qui ne se présente pas dans la pratique.
| Mais
C'est évidemment un cas bugué qui a ce qu'il mérite.
ABI
ABI
ABI
"Alain Naigeon" writes:
| "Gabriel Dos Reis" a écrit dans le
message
| news:
|
| > ABI
|
| ?
Application Binary Interface
"Alain Naigeon" <anaigeon@free.fr> writes:
| "Gabriel Dos Reis" <gdr@integrable-solutions.net> a écrit dans le
message
| news:
|
| > ABI
|
| ?
Application Binary Interface
"Alain Naigeon" writes:
| "Gabriel Dos Reis" a écrit dans le
message
| news:
|
| > ABI
|
| ?
Application Binary Interface
writes:
[...]
| > En particulier dans f.cc, le constructeur de copie est déclaré
| > inline alors dans dans g.cc, elle ne l'est pas. C'est bien une
| > violation des dispositions de la norme et le paragraphe que je
| > cite s'applique bien.
| D'accord. Mais il n'y a toujours pas d'exigence à ce que la
| définition soit présente. Alors, si on veut que le passage par
| régistre se fait en fonction de la sémantique du constructeur, on
| n'est pas avancé.
on a avancé. Ce qu'il faut bien voir, c'est que inline en C++ est un
changement d'ABI. Beaucoup de gens semblent ignorer ce point.
Ce que inline change ici, c'est de savoir si la fonction g() doit
attendre son argument dans le registre ou dans le tas. Parce que le
constructeur de copie est déclaré inline (même s'il n'est pas
utilisé), il instruit directement le compilateur de faire le choix
d'ABI correspondant.
[...]
| l'implémentation dans mon .hh. Mais d'après ce que je viens d'apprendre,
| il va falloir que je les déclare inline dans le .hh quand même.
Yep.
kanze@gabi-soft.fr writes:
[...]
| > En particulier dans f.cc, le constructeur de copie est déclaré
| > inline alors dans dans g.cc, elle ne l'est pas. C'est bien une
| > violation des dispositions de la norme et le paragraphe que je
| > cite s'applique bien.
| D'accord. Mais il n'y a toujours pas d'exigence à ce que la
| définition soit présente. Alors, si on veut que le passage par
| régistre se fait en fonction de la sémantique du constructeur, on
| n'est pas avancé.
on a avancé. Ce qu'il faut bien voir, c'est que inline en C++ est un
changement d'ABI. Beaucoup de gens semblent ignorer ce point.
Ce que inline change ici, c'est de savoir si la fonction g() doit
attendre son argument dans le registre ou dans le tas. Parce que le
constructeur de copie est déclaré inline (même s'il n'est pas
utilisé), il instruit directement le compilateur de faire le choix
d'ABI correspondant.
[...]
| l'implémentation dans mon .hh. Mais d'après ce que je viens d'apprendre,
| il va falloir que je les déclare inline dans le .hh quand même.
Yep.
writes:
[...]
| > En particulier dans f.cc, le constructeur de copie est déclaré
| > inline alors dans dans g.cc, elle ne l'est pas. C'est bien une
| > violation des dispositions de la norme et le paragraphe que je
| > cite s'applique bien.
| D'accord. Mais il n'y a toujours pas d'exigence à ce que la
| définition soit présente. Alors, si on veut que le passage par
| régistre se fait en fonction de la sémantique du constructeur, on
| n'est pas avancé.
on a avancé. Ce qu'il faut bien voir, c'est que inline en C++ est un
changement d'ABI. Beaucoup de gens semblent ignorer ce point.
Ce que inline change ici, c'est de savoir si la fonction g() doit
attendre son argument dans le registre ou dans le tas. Parce que le
constructeur de copie est déclaré inline (même s'il n'est pas
utilisé), il instruit directement le compilateur de faire le choix
d'ABI correspondant.
[...]
| l'implémentation dans mon .hh. Mais d'après ce que je viens d'apprendre,
| il va falloir que je les déclare inline dans le .hh quand même.
Yep.