[noob] Constructeur par recopie

Le
TSalm
Bonjour,

j'ai défini une classe où j'y ai défini un constructeur
par recopie :
// constructeur par recopie
pile_entier(pile_entier & p) {
cout << "Constructeur par recopie de taille " << *p.ent << endl;
ent = new int[p.taille];
taille = p.taille;
position = p.position;

for (int i=0;i<=position;++i) {
ent[i] = p.ent[i];
}
}

Voici deux cas, le premier fonctionne, l'autre non :

// Celui-ci fonctionne parfaitement :
pile_entier p;
/* traitements sur p */
pile_entier r = p;

// Mais celui là ne fonctionne pas :
pile_entier p;
pile_entier r;
/* traitements sur p */
r = p; // Me retournera une erreur : *** glibc detected *** double free or
corruption (!prev): 0x0804a008 ***

Je ne comprends pas très bien pourquoi, dans le deuxiéme cas, il ne
passe pas par mon constructeur par recopie !?

D'avance merci,
TSalm
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Michel Decima
Le #305716
TSalm wrote:
Bonjour,

j'ai défini une classe où j'y ai défini un constructeur
par recopie :
// constructeur par recopie
pile_entier(pile_entier & p) {
cout << "Constructeur par recopie de taille " << *p.ent << endl;
ent = new int[p.taille];
taille = p.taille;
position = p.position;

for (int i=0;i<=position;++i) {
ent[i] = p.ent[i];
}
}


tu pourrais passer le parametre par reference constante (mais ca n'a
rien a voir avec le probleme).

Voici deux cas, le premier fonctionne, l'autre non :

// Celui-ci fonctionne parfaitement :
pile_entier p;
/* traitements sur p */
pile_entier r = p;

// Mais celui là ne fonctionne pas :
pile_entier p;
pile_entier r;
/* traitements sur p */
r = p; // Me retournera une erreur : *** glibc detected *** double free or
corruption (!prev): 0x0804a008 ***

Je ne comprends pas très bien pourquoi, dans le deuxiéme cas, il ne
passe pas par mon constructeur par recopie !?


Parce que, dans le deuxieme cas, il ne s'agit pas de construction par
copie mais d'affectation. Et si tu ne fais rien, le compilateur te
donnes une version par defaut qui ne conviendra pas dans le cas present.

Donc, il te faudrait dans ta classe pile_entier une fonction avec le
prototype suivant:

void pile_entier::operator=( pile_entier const& p );

Mais bon... pourquoi ne pas encapsuler un std::vector<int> dans la
classe pile_entier ? Ca aurait l'avantage de laisser de coté ce genre de
problemes. Et tant qu'a faire, vu le nom de la classe, il y a aussi
std::stack<int> qui doit convenir.

TSalm
Le #305669
On Mon, 09 Apr 2007 23:26:05 +0200, Michel Decima wrote:

TSalm wrote:
j'ai défini une classe où j'y ai défini un constructeur
par recopie :
// constructeur par recopie
pile_entier(pile_entier & p) {
cout << "Constructeur par recopie de taille " << *p.ent << endl;
ent = new int[p.taille];
taille = p.taille;
position = p.position;

for (int i=0;i<=position;++i) {
ent[i] = p.ent[i];
}
}


tu pourrais passer le parametre par reference constante (mais ca n'a
rien a voir avec le probleme).

Voici deux cas, le premier fonctionne, l'autre non :

// Celui-ci fonctionne parfaitement :
pile_entier p;
/* traitements sur p */
pile_entier r = p;

// Mais celui là ne fonctionne pas :
pile_entier p;
pile_entier r;
/* traitements sur p */
r = p; // Me retournera une erreur : *** glibc detected *** double free or
corruption (!prev): 0x0804a008 ***

Je ne comprends pas très bien pourquoi, dans le deuxiéme cas, il ne
passe pas par mon constructeur par recopie !?


Parce que, dans le deuxieme cas, il ne s'agit pas de construction par
copie mais d'affectation. Et si tu ne fais rien, le compilateur te
donnes une version par defaut qui ne conviendra pas dans le cas present.

Donc, il te faudrait dans ta classe pile_entier une fonction avec le
prototype suivant:

void pile_entier::operator=( pile_entier const& p );



Merci. Ces explications sont parfaitement limpide !

Mais bon... pourquoi ne pas encapsuler un std::vector<int> dans la
classe pile_entier ? Ca aurait l'avantage de laisser de coté ce genre de
problemes. Et tant qu'a faire, vu le nom de la classe, il y a aussi
std::stack<int> qui doit convenir.


C'est simplement parce que j'apprends le C++ :)
Merci pour ces réponses.

TSalm


Michel Decima
Le #306387

Merci. Ces explications sont parfaitement limpide !


De rien. C'est un probleme classique au debut, après on s'y fait.

Mais bon... pourquoi ne pas encapsuler un std::vector<int> dans la
classe pile_entier ? Ca aurait l'avantage de laisser de coté ce genre de
problemes. Et tant qu'a faire, vu le nom de la classe, il y a aussi
std::stack<int> qui doit convenir.


C'est simplement parce que j'apprends le C++ :)


A moins que l'utilisation de pointeurs ne soit imposée, je te conseille
fortement de regarder std::vector<int>, ca ira plus vite pour la suite.


Publicité
Poster une réponse
Anonyme