Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[noob] Constructeur par recopie

3 réponses
Avatar
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

3 réponses

Avatar
Michel Decima
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.

Avatar
TSalm
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


Avatar
Michel Decima

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.