Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1588 connectés 

  FORUM HardWare.fr
  Programmation

  [C++] Affectation par dtor+ctor de copie ?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C++] Affectation par dtor+ctor de copie ?

n°149900
Musaran
Cerveaulté
Posté le 03-06-2002 à 12:50:46  profilanswer
 

J'aime bien définir l'opérateur d'affectation comme suit:

Code :
  1. Class Truc {
  2.   //...
  3.   Truc& operator=(const Truc & rh){
  4.     if(this != &rh){
  5.       this->Truc::~Truc() ; //détruire l'ancienne valeur
  6.       this->Truc::Truc(rh) ; //copier la nouvelle valeur avec le constructeur de copie
  7.     }
  8.     return *this ;
  9.   }
  10. }


Le concept me semble valable, ça marche, mais...
D'une part, Bjarne Stroustrup écrit qu'il faut éviter d'appeler directement les constructeurs/destructeurs si ce n'est pas indispensable.
D'autre part, je me demande si les constructeurs/destructeurs font un travail supplémentaire invisible. Par exemple, pour permettre à "throw" de détruire corectement les objets dont il ne connaît rien.
 
Qu'en pensez-vous ?


Message édité par Musaran le 06-03-2002 à 12:53:28

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
mood
Publicité
Posté le 03-06-2002 à 12:50:46  profilanswer
 

n°149906
LetoII
Le dormeur doit se réveiller
Posté le 03-06-2002 à 13:06:06  profilanswer
 

C pas térible en effet, mieux vaut faire une méthode de recopie qui va te recopier les données de l'objet source dans l'objet courrant et l'appeler dans l'oppérateur d'affectation et dans le constructeur de recopie, c'est plus propre et d'un résultat moin hazardeux.


---------------
Le Tyran
n°150402
Musaran
Cerveaulté
Posté le 03-06-2002 à 20:46:31  profilanswer
 

En quoi serait-ce hasardeux ?
 
Dans l'affectation, il faut bien libérer les anciennes ressources pour copier les nouvelles, et c'est exactement ce que font le destructeur et le constructeur de copie.
 
Il n'y a même pas besoin de mettre ce code à jour si on change la structure de la classe.
 
Je dirait presque que ceci aurait dû être l'opérateur d'affectation par défaut !
Mais je ne m'y connaît pas suffisamment pour voir d'éventuels problèmes...


Message édité par Musaran le 06-03-2002 à 20:46:46

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°150405
LetoII
Le dormeur doit se réveiller
Posté le 03-06-2002 à 20:56:09  profilanswer
 

Par ce qu'il est clairement dit qu'on ne doit pas appeler directement les constructeurs et destructeur, la chose n'étant pas prévu dans la norme tu ne peux absolument pas prévoir le comportement des compilateurs
En plus tu détruit un objet et après tu appel une méthode de cette objet ce qui est totalement abhérant (et ne passe pas avec certains compilos à mon avis)


Message édité par LetoII le 06-03-2002 à 21:01:52

---------------
Le Tyran
n°150673
Musaran
Cerveaulté
Posté le 04-06-2002 à 10:24:35  profilanswer
 

Dans son livre de référence du C++, Bjarne Stroustrup mentionne cette possibilité, et se contente de recommander de ne pas le faire s'il y a un autre moyen.
 
La "méthode" spéciale constructeur n'a, par définition, pas besoin d'un objet valide, puisque c'est justement elle qui est chargée de les rendre ainsi.
 
Et puis de toutes façon, quand quelque chose est interdit, je dois savoir pourquoi, sinon j'en tiens pas compte :lol: .


Message édité par Musaran le 06-04-2002 à 10:24:56

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°150858
LetoII
Le dormeur doit se réveiller
Posté le 04-06-2002 à 13:07:25  profilanswer
 

Faudra pas t'étonner si t'as des problèmes dans tes progs


---------------
Le Tyran
n°150860
pulco-citr​on
Posté le 04-06-2002 à 13:21:52  profilanswer
 

on peut aussi utiliser un new de placement :
new (this) Truc(param);
this est utilisé ici seulemnt comme un void* qui pointe vers un buffer de taille sizeof(Truc).
 
ça me semble a priori plus propre que ton truc.
 
 
 
 
ça me fait penser à un bout de code dégueulasse que j'ai vu une fois :
 
class Toto
{
public:
    static void f(void);
};
 
puis:
 
Toto * t = 0;
t->f();
 
ça marche à la compil et à l'exec, mais c'est inutile et dangereux

n°150862
LeGreg
Posté le 04-06-2002 à 13:34:23  profilanswer
 

L'appel au destructeur explicite est
valide tant que tu respectes certaines regles.
 
Cas classique d'appel au destructeur explicite apres un placement new:

Code :
  1. char memory[sizeof(MonObjet)];
  2. void* p = memory;
  3. MonObjet* m = new(p) MonObjet();
  4. // ...
  5. m->~MonObjet();


 
A noter, que l'appel au destructeur explicite est la seule facon de detruire un objet construit par placement new.
 
Par contre:  

Code :
  1. MonObjet toto*;
  2. /*..*/
  3. toto->~MonObjet();
  4. toto->MonObjet(nouvelle valeur); // c'est totalement stupide


 
Pourquoi est-ce stupide d'appeler le constructeur MonObjet() sur toto? tout simplement parce que tu ne sais pas de quel type est l'objet pointé par toto. Il peut etre 'MonObjet' comme il peut etre une classe fille.  
 
LeGreg


Message édité par LeGreg le 06-04-2002 à 13:39:51
n°151161
Musaran
Cerveaulté
Posté le 04-06-2002 à 18:14:49  profilanswer
 

letoII a écrit a écrit :

Faudra pas t'étonner si t'as des problèmes dans tes progs



Si c'est dangereux, illégitime ou bogué, je veux savoir pourquoi, c'est important pour moi.
 
Simplement dire "faut pas" ne me satisfait pas.
 

pulco-citron a écrit a écrit :

on peut aussi utiliser un new de placement


Le new, de placement ou pas, implique un appel a delete.
On ne peut pas demander à l'utilisateur de Truc d'y penser !
 
Quand à ton exemple "t->f()", il est effectivement dangereux, car il ne marchera pas si f n'est plus statique, et que le codeur risque de croire qu'il a un objet pointé.
 
C'est "Toto::f()" qu'il aurait fallu écrire.
Et pourtant... si on change le type pointé par t, ça ne suit pas le changement, et pire encore sans message d'erreur !
C'est pourquoi on peut préférer écrire "t->f()", qui est une méthode d'appel légitime pour une fonction de classe statique.
 

legreg a écrit a écrit :

L'appel au destructeur explicite est valide tant que tu respectes certaines regles.


Lesquelles ?
 
Ton exemple d'appel explicite au constructeur est effectivement à manier avec précaution.
Si le destructeur de la classe est virtuel, que se passe t'il ? On détruit un objet dérivé pour contruire un objet de base ?


Message édité par Musaran le 06-04-2002 à 18:16:41

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°151187
LetoII
Le dormeur doit se réveiller
Posté le 04-06-2002 à 18:32:24  profilanswer
 

Quand ces bien fait les destructeur d'une chaîne de dérivation sont virtuels ça ne pose normalement pas de problème de scôté là, le bon destructeur est appelée. Encore faut il que ça ai été bien fait au départ.


---------------
Le Tyran
mood
Publicité
Posté le 04-06-2002 à 18:32:24  profilanswer
 

n°151191
LetoII
Le dormeur doit se réveiller
Posté le 04-06-2002 à 18:34:12  profilanswer
 

Et puis au passage je trouve tout ça assez crade, mais bon c juste un avis personnel :D


---------------
Le Tyran
n°151196
LeGreg
Posté le 04-06-2002 à 18:38:51  profilanswer
 

Citation :

Lesquelles ?


 
Ben je t'ai donné la seule ou tu es obligé de le faire..
Tu peux appeler un destructeur plusieurs fois si tu t'assures
qu'il est reentrant.
 

Citation :

Ton exemple d'appel explicite au constructeur est effectivement à manier avec précaution.


 
Tu n'as pas compris: il n'est pas a manier avec precaution, il est a OUBLIER. Ne jamais coder comme ca, ce code est invalide en C++.
 

Citation :

Si le destructeur de la classe est virtuel, que se passe t'il ? On détruit un objet dérivé pour contruire un objet de base ?


 
Si le destructeur est virtuel on appelle destructeur de la classe fille. (pour un destructeur, "virtuel" ca a le meme sens que pour n'importe quelle fonction).
Et on ne construit pas un objet de base derriere puisque le code que j'ai ecrit est invalide. On ne l'ecrit jamais. (demande toi pourquoi il n'y a pas de constructeur virtuel en C++).
 
Pour faire ce que tu veux, passe par une fonction assign() et destroy() séparées que tu appelles depuis le constructeur et le destructeur. Ces fonctions seront eventuellement virtuelles suivant ce que tu veux faire.
 
A+
LeGreg


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation

  [C++] Affectation par dtor+ctor de copie ?

 

Sujets relatifs
copie de dbgrid[PHP&JS] Affectation de variables ?
Copie automatique d'un Contenu de CD apres son insertion --> HELP !copie du contenu d'un fichier dans un tableau
Problème copie de fichier C/Linux[Delphi] Obtenir un callback sur la copie d'un fichier
Problème de copie de fichier en c !!!![C++ - MCF?] copie de fichiers avancée
[XSL] Affectation de variableCopie de CD-Rom sur DD en Delphi ?
Plus de sujets relatifs à : [C++] Affectation par dtor+ctor de copie ?


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR