Envoyé par
killwin
Merci Bousks, j'ai étudié la chose qui pourra me servir plus tard. Mais j'ai pas opté pour cette solution car j'ai beaucoup de classes dans le même cas.
Merci koala, pour les 4 règles, sinon impossible de ne pas passer par un pointeur.
A vrai dire, les cas d'utilisation de pointeurs sont extrêmement rares!!!!
Pourquoi dis tu qu'il t'es impossible de ne pas passer par un pointeur
Ta classe ne pourrait-elle pas ressembler à
1 2 3 4 5 6 7 8 9 10
| class A {
public:
A(/* paramètres pour construire l'image*/);
private :
img b;
};
A::A(/* paramètre pour construire l'image*/):b(/*parametres*/)
{
} |
Tu t'éviterais ainsi le recours à l'allocation dynamique et tu n'aurais pas besoin de t'embêter avec le constructeur par copie, l'opéateur égal ou le destructeur: ceux qui seraient fournis d'office par le compilateur seraient suffisants
Donc en réfléchissant un peu plus j'ai écrit ça :
1 2 3 4 5 6 7 8 9 10 11
|
vector<A*> v;
void fonction(void) {
A **a;
a = (A**)malloc(sizeof(A*));
*a = new A();
v.push_back(*a);
} |
Ah, bon dieux!!!!! Que ca pique aux yeux!!!!
Si, vraiment, tu n'as pas d'autre choix d'utiliser un pointeur sur img, soit tu rend, purement et simplement, ta classe non copiable sous une forme proche de
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class A
{
public:
A():b(new img){}
~A() {delete b;}
/* en C++11, on peut faire
A(A const &) = delete;
A& operator=(A const &) = delete;
*/
private
/* en attendant C++1, on déclare le constructeur par copie et
* l'opérateur d'affectation privé et on ne les définit pas
*/
A(A const &);
A& operator= (A const &);
img * b;
}; |
et il s'agira alors d'utiliser un vecteur de pointeurs sur A sous une forme proche de
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| int main()
{
std::vector<A*> tab;
tab.push_back(new A() );
/* ou ou ou */
A * toadd=new A;
tab.push_back(toadd);
/* ne pas oublier, une fois que l'on en n'a plus besoin, de libérer
* la mémoire reliée à tous les pointeurs qui sont dans le vecteur
*/
for(std::vector<A*>::iterator it = tab.begin();it!=tab.end();++it)
delete *it;
return 0;
} |
soit on fait en sorte que chaque instance de A (y compris la copie) utilise un pointeur sur img qui lui est propre.
L'idéal étant alors d'utiliser l'idiome "copy and swap"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class A
{
public:
A():b(new img){}
A (A const & other):img(new img(other.b){}
A & operator = (A const & other)
{
A temp(other); // va appeler le constructeur par copie
std::swap(b,temp.b); // interverti le pointeur sur b entre
// l'instance en cours et la copie
retrurn *this;
} // la copie est détruite, delete est donc appelé sur temp.b, on évite
// les fuites mémoire
~A(){delete b;}
private:
img* delete;
}; |
et, l'utilisation peut rester aussi simple que
int main()
{
std::vector<A> tab;
tab.push_back(A());
/* ou ou ou */
A toadd;
tab.push_back(toadd);
retrun 0;
}
Comme ça j'ai un vecteur de pointeurs. J'utilise un pointeur sur pointeur puisque si la fonction se termine elle efface le premier pointage.
Oublie la notion de pointeurs pour le passage d'argument à une fonction et pense "référence"...
De plus, évite autant que possible d'utiliser des variables globales, ca ne présente que des inconvénients (encore plus que les pointeurs de pointeurs dirais-je )
Si tu veux vraiment qu'il y ait une fonction qui s'occupe de tout (la création du pointeur et l'insertion dans le tableau) écrit plutot quelque chose comme
1 2 3 4 5
| vois foo(std::vector<A*> & tab)
{
A * temp = new A;
tab.push_back(temp);
} |
Qu'en pensez-vous ? En tout cas ça marche.
[/QUOTE]
Tant qu'on y est j'ai une autre question, delete(obj); obj vaudra null après un delete ? Merci[/QUOTE]
D'abord, ce n'est pas delete(obj); mais simplement delete obj; et ensuite, obj ne vaudra null que si tu le met explicitement à nul
Dans le code de A que j'ai donné, b n'est pas mis à NULL après avoir été détruit, mais ce n'est pas grave: comme l'objet a été détruit, on n'essaiera pas d'accéder à ce pointeur par la suite
Par contre, si tu utilise un vecteur de pointeurs, il faudra être attentif, si, à un moment, tu souhaites détruire l'un des élément du vecteur:
Soit tu devra veiller à mettre le pointeur en question à NULL, mais il faudra alors vérifier chaque élément pour s'assurer qu'il ne vaut pas NULL avant d'essayer d'accéder à ce qu'il pointe:
delete tab[i];
tab[i] = NULL;
1 2 3 4 5 6
|
/* pour l'accès */
if(tab[i]!= NULL)
{
/* ce qu'il faut faire */
} |
soit, et c'est surement le plus facile, il faut veiller à retirer les pointeurs devenus invalides
1 2
| delete tab[i];
tab.erase(i); |
Partager