[C++] Appel d'un constructeur dans un constructeur via placement new

Appel d'un constructeur dans un constructeur via placement new [C++] - C++ - Programmation

Marsh Posté le 18-09-2003 à 18:18:37    

Bijour, je pense que celle-là elle est pour taz:
 
donc voici un bout de classe:
 

Code :
  1. class MaterialDescription
  2. {
  3. public:
  4.  BML_Material Mat;
  5.  int TextureChannel;
  6.  Matrix3 uvMatrix;
  7.  float ClipW,ClipH,ClipU,ClipV;
  8. MaterialDescription();
  9. MaterialDescription( StdMat *Sm, TimeValue Tm );
  10. void GetFromMAX(StdMat *Sm, TimeValue Tm );
  11. }
  12. MaterialDescription::MaterialDescription() : ClipU(0), ClipV(0), ClipW(1), ClipH(1)
  13. {
  14. ZeroMemory( &Mat, sizeof( BML_Material ) );
  15. uvMatrix.IdentityMatrix();
  16. }
  17. MaterialDescription::MaterialDescription( StdMat *Sm, TimeValue Tm )
  18. {
  19. new (this) MaterialDescription;
  20. GetFromMAX( Sm, Tm );
  21. }


 
je voulais si il existait un autre moyen d'appeller (autre que via le placement new) le constructeur MaterialDescription (sans paramètres) dans le constructeur MaterialDescription( StdMat *Sm, TimeValue Tm ).
 
désolé si je poses une question bête (il en fo bien de temps en temps)
 
paske:
 

Code :
  1. MaterialDescription::MaterialDescription( StdMat *Sm, TimeValue Tm )
  2. {
  3. MaterialDescription();
  4. GetFromMAX( Sm, Tm );
  5. }


 
compile, mes les Clip,uvMatrix & co ne sont pas initialisés....
 
(or VC 7.1 bug ?)


Message édité par bjone le 18-09-2003 à 18:19:59
Reply

Marsh Posté le 18-09-2003 à 18:18:37   

Reply

Marsh Posté le 18-09-2003 à 18:20:23    

Code :
  1. MaterialDescription::MaterialDescription( StdMat *Sm, TimeValue Tm ) : MaterialDescription()


?
 

Code :
  1. void GetFromMAX(StdMat *Sm, TimeValue Tm );


 
[:lacuna coil]

Reply

Marsh Posté le 18-09-2003 à 18:24:29    

Code :
  1. MaterialDescription::MaterialDescription( StdMat *Sm, TimeValue Tm ) : MaterialDescription()


 
c'est que j'ai essayé au tout début mé y veux pas :heink:  
 
sinon comme tu vois je me remets à 3DSMax  :hello:

Reply

Marsh Posté le 18-09-2003 à 18:27:27    

BJOne a écrit :

[cpp]
sinon comme tu vois je me remets à 3DSMax  :hello:  


 
qu'est ce que tu nous prepare de beau ?  
 

Reply

Marsh Posté le 18-09-2003 à 18:28:48    

chrisbk a écrit :


 
qu'est ce que tu nous prepare de beau ?  
 
 


 
un truc qui marche déjà ce serait un bon début :D
 
(au fur et à mesure que je fais mumuse avec des modèles, je fais: ho là ça mairde à l'export, méporquédidoncça ?)

Reply

Marsh Posté le 18-09-2003 à 18:32:07    

BJOne a écrit :


 
un truc qui marche déjà ce serait un bon début :D
 
(au fur et à mesure que je fais mumuse avec des modèles, je fais: ho là ça mairde à l'export, méporquédidoncça ?)


 
fais comme moi : delegue :D
des idées a partager ? Tu comptes implanter quoi comme fitures ? un screenshot ? [:cupra]
 
(on (enfin, le collegue :D) a tout refait les mater max. Je dis ca paske visiblement t'as les pieds dedans, amuse toi bien :D)

Reply

Marsh Posté le 18-09-2003 à 18:34:45    

oulà je paufine l'export texture (avec toutes les conneries de Crop & co que j'avais pas vu avant....)
 
pi après dans la liste des truc à faire, c'est avoir du bump qui marche  :wahoo:

Reply

Marsh Posté le 18-09-2003 à 18:35:39    

Tu mets le code de ton constructeur par defaut dans une fonction membre et tu l'appelles si besoin.

Reply

Marsh Posté le 18-09-2003 à 18:36:36    

BJOne a écrit :

oulà je paufine l'export texture (avec toutes les conneries de Crop & co que j'avais pas vu avant....)
 
pi après dans la liste des truc à faire, c'est avoir du bump qui marche  :wahoo:  


 
ben si tu trouves un truc qui explique comment calculer les vecteurs tangents ca serait sympa :O
Tout ce que je trouve c'est des "bah utilise D3DXMachinTruc" [:dawa]
super

Reply

Marsh Posté le 18-09-2003 à 18:37:51    

Kristoph a écrit :

Tu mets le code de ton constructeur par defaut dans une fonction membre et tu l'appelles si besoin.


 
ouais, c'est ce que je comptais faire au final, mais à titre intellectuel, j'aimerais savoir, si dans le cas ou y'aurais à appeller un constructeur dans un autre, le placement new est ce qu'il y a de plus adapté....

Reply

Marsh Posté le 18-09-2003 à 18:37:51   

Reply

Marsh Posté le 18-09-2003 à 18:38:54    

chrisbk a écrit :


 
ben si tu trouves un truc qui explique comment calculer les vecteurs tangents ca serait sympa :O
Tout ce que je trouve c'est des "bah utilise D3DXMachinTruc" [:dawa]
super


 
j'ai vu ça, mais comme je suis pas à ce stade, j'en sais pas trop plus...

Reply

Marsh Posté le 18-09-2003 à 18:43:10    

BJOne a écrit :


 
ouais, c'est ce que je comptais faire au final, mais à titre intellectuel, j'aimerais savoir, si dans le cas ou y'aurais à appeller un constructeur dans un autre, le placement new est ce qu'il y a de plus adapté....


 
Je pense que c'est très douteux quand même. Surtout au niveau de l'appel aux constructeurs des classes parentes.

Reply

Marsh Posté le 18-09-2003 à 18:46:45    

ton truc est suicidaire au sens littéral. le C++ n'est pas Java et ne propose pas de définir un constructeur en fonction d'un autre .|
 
 
quant à  ZeroMemory( &Mat, sizeof( BML_Material ) ); , y a des grandes chances que y est des flottant dans ta matrice et la représentation binaire 0x00000000 est invalide et en tous les cas != 0.0

Reply

Marsh Posté le 18-09-2003 à 18:46:52    

Kristoph a écrit :


 
Je pense que c'est très douteux quand même. Surtout au niveau de l'appel aux constructeurs des classes parentes.


 
à oui ça c'est effectivement à éviter....
 
mais du moment qu'on appelle un constructeur du "même niveau" ??

Reply

Marsh Posté le 18-09-2003 à 18:48:17    

dons plusieurs solution :  
1) plusieurs constructeurs avec des arguments pas défaut
2) des fabriques statiques

Reply

Marsh Posté le 18-09-2003 à 18:49:58    

Taz a écrit :

ton truc est suicidaire au sens littéral. le C++ n'est pas Java et ne propose pas de définir un constructeur en fonction d'un autre .|
 
 
quant à  ZeroMemory( &Mat, sizeof( BML_Material ) ); , y a des grandes chances que y est des flottant dans ta matrice et la représentation binaire 0x00000000 est invalide et en tous les cas != 0.0


 
t'inquiètes pas c'est pas une matrice (Mat:matériaux)...
la seule matrice c'est uvMatrix, elle mise à I dans le premier constructeur.
 
de toutes façon, je vais passer par une méthode qui réinitialise les membres de l'instance, comme ça je reparts d'un truc sain entre plusieurs GetFromMax (chose qui ne devrait jamais arriver en fait, mais ça sera mieux à tous les étages)


Message édité par bjone le 18-09-2003 à 18:50:46
Reply

Marsh Posté le 18-09-2003 à 18:55:05    

le problème est double:
1) la mémoire allouée pour this ne t'appartient pas
2) avec ton écriture, this est déjà construit et intègre, et en reconstuisant dessus, tu provoques sans doute des fuites de mémoires et autres effets indésirables, puisqu'aucun destructeur n'est appelé, etc...
 
et c'est très crade, j'ai encore tout un tas de bonnes raisons, mais je suis sur que tu vas être capable de résoudre ça bien. ton problème est compréhensible, mais ton volume de code est minime, dans le cas contraire : - fais une fonction membre privée Init(), - si beaucoup de paramètres au constructeur, on peut facilement faire une facilité pour avoir un comportement comme avec des paramètres nommés

Reply

Marsh Posté le 18-09-2003 à 19:01:12    

Taz a écrit :

le problème est double:
1) la mémoire allouée pour this ne t'appartient pas
2) avec ton écriture, this est déjà construit et intègre, et en reconstuisant dessus, tu provoques sans doute des fuites de mémoires et autres effets indésirables, puisqu'aucun destructeur n'est appelé, etc...
 
et c'est très crade, j'ai encore tout un tas de bonnes raisons, mais je suis sur que tu vas être capable de résoudre ça bien. ton problème est compréhensible, mais ton volume de code est minime, dans le cas contraire : - fais une fonction membre privée Init(), - si beaucoup de paramètres au constructeur, on peut facilement faire une facilité pour avoir un comportement comme avec des paramètres nommés


 
attention y'a normalement pas de double construction/allocation avec le placement new...

Reply

Marsh Posté le 18-09-2003 à 19:25:49    

toi t'as pas l'air de voir que l'allocation et la construction sont 2 choses bien distinctes ? il y a effectivement double construction

Reply

Marsh Posté le 18-09-2003 à 19:35:26    

Taz a écrit :

toi t'as pas l'air de voir que l'allocation et la construction sont 2 choses bien distinctes ? il y a effectivement double construction


 
je suis d'accord, en fait je m'explique mal (je crois que l'on est d'accord au final)
 

Reply

Marsh Posté le 18-09-2003 à 19:36:08    

BJOne a écrit :

je crois que l'on est d'accord au final

alors tu fais quoi comme solution ?

Reply

Marsh Posté le 18-09-2003 à 19:46:19    

en fait si l'on fait ça:
 
class T;
 
T *ptr= new T;
---
delete ptr;
 
 
-----------
 
c'est équivalent à:
 
ptr = alloc_quelquonque(sizeof(T));
new (ptr) T;
----
ptr->~T();
libere_quelquonque(ptr);
 
si l'on se limite à ce contexte ok...
 
---------------------------
 
donc avoir:
 
class T
{
  public:
     T()
     {
       .... pleins de trucs ....
     }
 
     T( machin param )
     {
        new (this) T;
        truc_fait_avec(param);
     }
}
 
fera que le code de T() sera appellé dans T( machin param ), mais l'allocation mémoire est faite avant, this pointant sur l'espace mémoire alloué. d'un point de vue lecture on a double construction, mais si les constructions se complémentent sans "répétition", on conserve la cohérence (pas de fuite mémoire, construction/destruction symétrique en cas de pointeurs)...
 

Reply

Marsh Posté le 18-09-2003 à 19:47:56    

Taz a écrit :

alors tu fais quoi comme solution ?


 
je suis passé par une méthode Clear ou (Init comme tu veux), de toutes façon il fallait absolument que mes ClipU & co soient initialisés pour GetFromMax....
 
en fait le but c'était d'avoir quelques discussion autour du placement new dans ce cas là ;)


Message édité par bjone le 18-09-2003 à 19:48:50
Reply

Marsh Posté le 18-09-2003 à 19:49:13    

ben non, y a fuite de mémoire à tous les coups. mais une string ou un vector dedans, et reviens m'en parlé, tu verras.
 
je désapprouve complètement cette construction

Reply

Marsh Posté le 18-09-2003 à 19:50:05    

ptr = alloc_quelquonque(sizeof(T));
new (ptr) T;
----
ptr->~T();
libere_quelquonque(ptr);  
 
 
qui est très laid

Reply

Marsh Posté le 18-09-2003 à 19:50:35    

Taz a écrit :

ben non, y a fuite de mémoire à tous les coups. mais une string ou un vector dedans, et reviens m'en parlé, tu verras.
 
je désapprouve complètement cette construction


 
a ouais, là je vois mieux effectivement, y'a double construction pour les objets membres.
oki là je suis te suis ;)

Reply

Marsh Posté le 18-09-2003 à 19:52:08    

Taz a écrit :

ptr = alloc_quelquonque(sizeof(T));
new (ptr) T;
----
ptr->~T();
libere_quelquonque(ptr);  
 
 
qui est très laid


 
c'est pas faux... mais c'est une écriture possible ;)

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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