Operator= et membres constants

Operator= et membres constants - C++ - Programmation

Marsh Posté le 17-01-2006 à 23:39:10    

Bonjour à tous,
Voici un problème auquel je n'arrive pas a trouver de réponse:
je possède une classe A

Code :
  1. class A {
  2. public:
  3. A(const std::string &une_chaine) : une_chaine_constante(une_chaine) {};
  4. A(const A& );
  5. A& operator=(const A& );
  6. ~A();
  7. private:
  8. const std::string une_chaine_constante;
  9. };


 
je dispose dans une autre classe d'un vector du type vector<A>.
Ma méthode d'ajout dans le vector d'un objet A est :  

Code :
  1. bool ajout(const &std::string une_chaine)
  2. {
  3. A a(une_chaine);
  4. mon_vector.push_back(a);
  5. }


 
Or c'est là ou intervient mon problème :
Le vector désire visiblement utiliser l'operator= pour effectuer la copie dans le vecteur.
Ceci ne posserait pas de problème si je n'avais pas ce terme constant "une_chaine_constante" que l'operator= ne peut pas toucher.
je ne sais donc pas comment réécrire cet opérateur  
selon ce que je trouve il faudrait une méthode du genre

Code :
  1. A& A::operator=(const A& a)
  2. {
  3. if(this!=a)
  4. {
  5. ....
  6. }
  7. return *this;
  8. }


Mais je ne sais pas comment bien l'écrire afin que vector accepte que je fasse un push_back de A ......
Merci par avance.
Caddie


Message édité par caddie le 18-01-2006 à 13:49:24
Reply

Marsh Posté le 17-01-2006 à 23:39:10   

Reply

Marsh Posté le 18-01-2006 à 00:20:42    

réponse simple : le constructeur de copie, l'operateur d'affectation, le constructeur, n'ont pas besoin d'etre déclaré dans ton cas. Ils le seront implicitement, et seront définis de la bonne manière le cas échéant.
Laisse faire le compilateur, soit faignant/productif.

Reply

Marsh Posté le 18-01-2006 à 00:25:29    

Pour moi l'ensemble d'instructions :

Code :
  1. bool ajout(const std::string une_chaine)
  2. {
  3. A a(une_chaine);
  4. mon_vector.push_back(a);
  5. }


induit l'appel implicite au constructeur de copie de A.
 
Ne faudrait-il pas définir le constructeur de copie

A(const A& );


comme ceci:
 

Code :
  1. A(const A& obj)
  2. :une_chaine_constante(obj.une_chaine_constante)
  3. {
  4. }


 
?
 
Edit : fab m'a devancé pendant que j'écrivais. Voir si ce que je propose fonctionne.


Message édité par slash33 le 18-01-2006 à 00:27:55
Reply

Marsh Posté le 18-01-2006 à 08:34:45    

J'avais laissé mon compilo (VC7) faire, mais a la compilation il me crache a la gueule en me disant :  
"error C2582: 'operator =' fonction non disponible dans 'A' ' et ceci de me remener au fichier xutility
Cette erreur disparaissant si j'enlève le push_back.

Reply

Marsh Posté le 18-01-2006 à 08:52:49    

pas trop grand chose a voir, mais :
 

Code :
  1. bool ajout(const std::string une_chaine)


 
passe plutot ton param par reference (jpense c'est un oubli / recopie foireuse, mais bon)

Reply

Marsh Posté le 18-01-2006 à 12:58:16    

chrisbk a écrit :

pas trop grand chose a voir, mais :
 

Code :
  1. bool ajout(const std::string une_chaine)


 
passe plutot ton param par reference (jpense c'est un oubli / recopie foireuse, mais bon)


 
Oui ça c'est juste une erreur en écrivant sur le forum

Reply

Marsh Posté le 18-01-2006 à 13:24:11    

caddie a écrit :

"error C2582: 'operator =' fonction non disponible dans 'A' ' et ceci de me remener au fichier xutility
Cette erreur disparaissant si j'enlève le push_back.

T'es sur de l'avoir enlevé ton A& operator=(const A& );  ?

Reply

Marsh Posté le 18-01-2006 à 13:50:57    

push a écrit :

T'es sur de l'avoir enlevé ton A& operator=(const A& );  ?


 
 
 
Oui quand j'ai ce message d'erreur, je n'ai aucune redéfinition d'opérateur ni du constructeur par copie dans ma classe A.
Il se trouve que si j'enlève le const de ma chaine de la classe A alors le push_back fonctionne. Le problème c'est que j'aimerai que ma chaine membre de la classe A reste constante ...

Reply

Marsh Posté le 18-01-2006 à 14:17:27    

ouaip, t'es obligé de redéfinir l'opérateur d'affectaction

Reply

Marsh Posté le 18-01-2006 à 14:19:13    

caddie a écrit :

Le problème c'est que j'aimerai que ma chaine membre de la classe A reste constante ...


 
pkoi ? elle est private, non partagé, donc bon...

Reply

Marsh Posté le 18-01-2006 à 14:19:13   

Reply

Marsh Posté le 18-01-2006 à 14:28:10    

chrisbk> tiens sûrement question con mais pq vector utilise l'operateur d'affectation et pas le constructeur de recopie au moment du push_back ? ça résoudrait le problème du const là non ? enfin je dis ça je sais même pas à quoi ressemble vector

Reply

Marsh Posté le 18-01-2006 à 14:45:44    

push a écrit :

chrisbk> tiens sûrement question con mais pq vector utilise l'operateur d'affectation et pas le constructeur de recopie au moment du push_back ? ça résoudrait le problème du const là non ? enfin je dis ça je sais même pas à quoi ressemble vector


 
Exactement la question que je me pose aussi.... parce que du coup je l'ai dans l'os mon truc.
Mais Chrisbk tu as raison je vais pas le mettre en const et au moins ca réglera le problème.

Reply

Marsh Posté le 18-01-2006 à 14:56:32    

push a écrit :

chrisbk> tiens sûrement question con mais pq vector utilise l'operateur d'affectation et pas le constructeur de recopie au moment du push_back ? ça résoudrait le problème du const là non ? enfin je dis ça je sais même pas à quoi ressemble vector


 
ouais je sais pas trop non plus, chui pas allé voir en detail. J'imagine que vector s'alloue un tableau privé pour stocker les elements (cf la fonction reserve()) et que quand tu fais push_back il fait (grosso merdo) un truc genre :
 
tableau[size] = machin;
size++;
 

Reply

Marsh Posté le 18-01-2006 à 17:12:31    

pas forcement, vector possede une zone alouée et à l'interieur de celle-ci une zone construite donc ca doit  plutot etre une reallocation si necessaire et une construction par placement new (avec size++), enfin ca doit dependre de l'implementation
 
moi ce que je trouves bizarre c'est que si un membre est constant alors la sémantique de opérateur = fournie par le compilateur devient illégale
faut donc dans ce cas le redefinir et dire qu'il ne fais rien (dans ce cas)
A& operator=(const A& ) { return *this; }

Reply

Marsh Posté le 18-01-2006 à 18:22:04    

skelter a écrit :

faut donc dans ce cas le redefinir et dire qu'il ne fais rien (dans ce cas)
A& operator=(const A& ) { return *this; }


Et se retrouver avec une zone mémoire non initialisée ?

Reply

Marsh Posté le 18-01-2006 à 19:40:17    

Tiens, la "chaine constante" a maintenant son const. L'ennui, c'est qu'une classe qui contient une donnée membre const non static, n'est pas assignable.  
Les séquences standards requierent au type de leur paramètre générique, d'etre copie-constructible et assignable. (les contraintes des templates ne peuvent, pour l'instant, pas etre exprimé élégamment, mais ça va venir).
 
donc, soit tu enleves le const, soit tu ajoutes un static ...


Message édité par ++fab le 18-01-2006 à 19:41:26
Reply

Marsh Posté le 18-01-2006 à 21:30:05    

bin enlever le const, paske bon, static ca change un peu pas mal de chose [:god]

Reply

Marsh Posté le 21-01-2006 à 13:20:53    

pour affecter une variable const non static moi j'utiliserai:
 
 
const_cast<std::string&>(une_chaine_constante) = une_chaine;

Reply

Marsh Posté le 21-01-2006 à 13:34:32    

mais arrêtez vos bêtises. soit c'est constant, soit ça l'est pas bordel. si tu marques t'as chaine const et qu'apres tu veux la modifier, ben elle est pas const c'est tout putain.

Reply

Marsh Posté le 21-01-2006 à 13:47:49    

bein à la base y voulait juste stocker ses objets dans un vector

Reply

Marsh Posté le 21-01-2006 à 13:49:58    

chicotruss a écrit :

pour affecter une variable const non static moi j'utiliserai:
 
 
const_cast<std::string&>(une_chaine_constante) = une_chaine;


 
nan bin nan, alors si c'est pour faire ca la marque pas const quoi [:el g]

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed