Le samedi 11 octobre 2003 à 20:34:56, Alexandre a écrit dans fr.comp.lang.c++ :
Quand on a un pointeur sur un objet valide, on peut (je crois) appeler le destructeur, puis le constructeur. Mais bon, c'est de la sale bidouille -- je préfère ne jamais essayer ;-)
Comme ça ?
OBJET *ptr; ptr = new OBJET ; // appel du constructeur delete ptr; // appel du destructeur ptr = new OBJET; // appel du constructeur
Non, comme ça :
OBJET *ptr; ptr = new OBJET ; // appel du constructeur ptr->~OBJET(); // appel du destructeur ptr->OBJET(); // appel du constructeur
-- ___________ 2003-10-11 20:48:50 _/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net _L_) Il faut donc que les hommes commencent -'(__) par n'être pas fanatiques pour mériter _/___(_) la tolérance. -- Voltaire, 1763
Le samedi 11 octobre 2003 à 20:34:56, Alexandre a écrit dans
fr.comp.lang.c++ :
Quand on a un pointeur sur un objet valide, on peut (je crois) appeler
le destructeur, puis le constructeur. Mais bon, c'est de la sale
bidouille -- je préfère ne jamais essayer ;-)
Comme ça ?
OBJET *ptr;
ptr = new OBJET ; // appel du constructeur
delete ptr; // appel du destructeur
ptr = new OBJET; // appel du constructeur
Non, comme ça :
OBJET *ptr;
ptr = new OBJET ; // appel du constructeur
ptr->~OBJET(); // appel du destructeur
ptr->OBJET(); // appel du constructeur
--
___________ 2003-10-11 20:48:50
_/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net
_L_) Il faut donc que les hommes commencent
-'(__) par n'être pas fanatiques pour mériter
_/___(_) la tolérance. -- Voltaire, 1763
Le samedi 11 octobre 2003 à 20:34:56, Alexandre a écrit dans fr.comp.lang.c++ :
Quand on a un pointeur sur un objet valide, on peut (je crois) appeler le destructeur, puis le constructeur. Mais bon, c'est de la sale bidouille -- je préfère ne jamais essayer ;-)
Comme ça ?
OBJET *ptr; ptr = new OBJET ; // appel du constructeur delete ptr; // appel du destructeur ptr = new OBJET; // appel du constructeur
Non, comme ça :
OBJET *ptr; ptr = new OBJET ; // appel du constructeur ptr->~OBJET(); // appel du destructeur ptr->OBJET(); // appel du constructeur
-- ___________ 2003-10-11 20:48:50 _/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net _L_) Il faut donc que les hommes commencent -'(__) par n'être pas fanatiques pour mériter _/___(_) la tolérance. -- Voltaire, 1763
Serge Paccalin
Le samedi 11 octobre 2003 à 20:34:56, Alexandre a écrit dans fr.comp.lang.c++ :
Quand on a un pointeur sur un objet valide, on peut (je crois) appeler le destructeur, puis le constructeur. Mais bon, c'est de la sale bidouille -- je préfère ne jamais essayer ;-)
Comme ça ?
OBJET *ptr; ptr = new OBJET ; // appel du constructeur delete ptr; // appel du destructeur ptr = new OBJET; // appel du constructeur
Non, comme ça :
OBJET *ptr; ptr = new OBJET ; // allocation+appel du constructeur ptr->~OBJET(); // appel du destructeur ptr->OBJET(); // appel du constructeur
-- ___________ 2003-10-11 20:48:50 _/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net _L_) Il faut donc que les hommes commencent -'(__) par n'être pas fanatiques pour mériter _/___(_) la tolérance. -- Voltaire, 1763
Le samedi 11 octobre 2003 à 20:34:56, Alexandre a écrit dans
fr.comp.lang.c++ :
Quand on a un pointeur sur un objet valide, on peut (je crois) appeler
le destructeur, puis le constructeur. Mais bon, c'est de la sale
bidouille -- je préfère ne jamais essayer ;-)
Comme ça ?
OBJET *ptr;
ptr = new OBJET ; // appel du constructeur
delete ptr; // appel du destructeur
ptr = new OBJET; // appel du constructeur
Non, comme ça :
OBJET *ptr;
ptr = new OBJET ; // allocation+appel du constructeur
ptr->~OBJET(); // appel du destructeur
ptr->OBJET(); // appel du constructeur
--
___________ 2003-10-11 20:48:50
_/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net
_L_) Il faut donc que les hommes commencent
-'(__) par n'être pas fanatiques pour mériter
_/___(_) la tolérance. -- Voltaire, 1763
Le samedi 11 octobre 2003 à 20:34:56, Alexandre a écrit dans fr.comp.lang.c++ :
Quand on a un pointeur sur un objet valide, on peut (je crois) appeler le destructeur, puis le constructeur. Mais bon, c'est de la sale bidouille -- je préfère ne jamais essayer ;-)
Comme ça ?
OBJET *ptr; ptr = new OBJET ; // appel du constructeur delete ptr; // appel du destructeur ptr = new OBJET; // appel du constructeur
Non, comme ça :
OBJET *ptr; ptr = new OBJET ; // allocation+appel du constructeur ptr->~OBJET(); // appel du destructeur ptr->OBJET(); // appel du constructeur
-- ___________ 2003-10-11 20:48:50 _/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net _L_) Il faut donc que les hommes commencent -'(__) par n'être pas fanatiques pour mériter _/___(_) la tolérance. -- Voltaire, 1763
Serge Paccalin
Le samedi 11 octobre 2003 à 20:34:56, Alexandre a écrit dans fr.comp.lang.c++ :
Quand on a un pointeur sur un objet valide, on peut (je crois) appeler le destructeur, puis le constructeur. Mais bon, c'est de la sale bidouille -- je préfère ne jamais essayer ;-)
Comme ça ?
OBJET *ptr; ptr = new OBJET ; // appel du constructeur delete ptr; // appel du destructeur ptr = new OBJET; // appel du constructeur
Non, plutôt comme ça :
OBJET *ptr; ptr = new OBJET ; // allocation+appel du constructeur ptr->~OBJET(); // appel du destructeur ptr->OBJET(); // appel du constructeur
Mais ça ne doit pas marcher. Il faut sans doute utiliser un « placement new » : new(ptr) OBJET;
-- ___________ 2003-10-11 20:48:50 _/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net _L_) Il faut donc que les hommes commencent -'(__) par n'être pas fanatiques pour mériter _/___(_) la tolérance. -- Voltaire, 1763
Le samedi 11 octobre 2003 à 20:34:56, Alexandre a écrit dans
fr.comp.lang.c++ :
Quand on a un pointeur sur un objet valide, on peut (je crois) appeler
le destructeur, puis le constructeur. Mais bon, c'est de la sale
bidouille -- je préfère ne jamais essayer ;-)
Comme ça ?
OBJET *ptr;
ptr = new OBJET ; // appel du constructeur
delete ptr; // appel du destructeur
ptr = new OBJET; // appel du constructeur
Non, plutôt comme ça :
OBJET *ptr;
ptr = new OBJET ; // allocation+appel du constructeur
ptr->~OBJET(); // appel du destructeur
ptr->OBJET(); // appel du constructeur
Mais ça ne doit pas marcher. Il faut sans doute utiliser un « placement
new » : new(ptr) OBJET;
--
___________ 2003-10-11 20:48:50
_/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net
_L_) Il faut donc que les hommes commencent
-'(__) par n'être pas fanatiques pour mériter
_/___(_) la tolérance. -- Voltaire, 1763
Le samedi 11 octobre 2003 à 20:34:56, Alexandre a écrit dans fr.comp.lang.c++ :
Quand on a un pointeur sur un objet valide, on peut (je crois) appeler le destructeur, puis le constructeur. Mais bon, c'est de la sale bidouille -- je préfère ne jamais essayer ;-)
Comme ça ?
OBJET *ptr; ptr = new OBJET ; // appel du constructeur delete ptr; // appel du destructeur ptr = new OBJET; // appel du constructeur
Non, plutôt comme ça :
OBJET *ptr; ptr = new OBJET ; // allocation+appel du constructeur ptr->~OBJET(); // appel du destructeur ptr->OBJET(); // appel du constructeur
Mais ça ne doit pas marcher. Il faut sans doute utiliser un « placement new » : new(ptr) OBJET;
-- ___________ 2003-10-11 20:48:50 _/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net _L_) Il faut donc que les hommes commencent -'(__) par n'être pas fanatiques pour mériter _/___(_) la tolérance. -- Voltaire, 1763
Fabien LE LEZ
On Sat, 11 Oct 2003 20:34:56 +0200, "Alexandre" wrote:
On Sat, 11 Oct 2003 16:10:21 +0200, Nicolas Aunai ç wrote:
ma_classe c(c1); // instanciation de c a partir de c1
ma_classe cÁ;
Sauf si le constructeur est explicite, auquel cas, seule la première écriture est valide.
-- Loïc
James Kanze
Serge Paccalin writes:
|> Le samedi 11 octobre 2003 à 20:34:56, Alexandre a écrit dans |> fr.comp.lang.c++ :
|> >> Quand on a un pointeur sur un objet valide, on peut (je crois) |> >> appeler le destructeur, puis le constructeur. Mais bon, c'est de |> >> la sale bidouille -- je préfère ne jamais essayer ;-)
|> > Comme ça ?
|> > OBJET *ptr; |> > ptr = new OBJET ; // appel du constructeur |> > delete ptr; // appel du destructeur |> > ptr = new OBJET; // appel du constructeur
|> Non, plutôt comme ça :
|> OBJET *ptr; |> ptr = new OBJET ; // allocation+appel du constructeur |> ptr->~OBJET(); // appel du destructeur |> ptr->OBJET(); // appel du constructeur
|> Mais ça ne doit pas marcher. Il faut sans doute utiliser un |> « placement new » : new(ptr) OBJET;
En effet. En fait, il est impossible à « appeler » le constructeur ; il est toujours appelé implicitement, lors de l'initialisation dans une définition, lors d'une expression de new, ou lors d'une conversion de type. En revanche, ce dernier se ressemble beaucoup à un appel explicit, surtout quand le constructeur n'a pas de paramètres ou qu'il en a plus d'un. N'empêche que le résultat, c'est toujours un nouvel objet, temporaire.
Fabien s'est trompé aussi en disant qu'il faut absolument appeler le destructeur d'abord. Si le destructeur est trivial, on n'est pas obligé à l'appeler, et quelque chose comme :
std::complex< double > z ; // ... new ( &z ) std::complex< double >( 1.0, 2.0 ) ;
est parfaitement légal (mais totalement sans intérêt).
-- James Kanze mailto: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
|> Le samedi 11 octobre 2003 à 20:34:56, Alexandre a écrit dans
|> fr.comp.lang.c++ :
|> >> Quand on a un pointeur sur un objet valide, on peut (je crois)
|> >> appeler le destructeur, puis le constructeur. Mais bon, c'est de
|> >> la sale bidouille -- je préfère ne jamais essayer ;-)
|> > Comme ça ?
|> > OBJET *ptr;
|> > ptr = new OBJET ; // appel du constructeur
|> > delete ptr; // appel du destructeur
|> > ptr = new OBJET; // appel du constructeur
|> Non, plutôt comme ça :
|> OBJET *ptr;
|> ptr = new OBJET ; // allocation+appel du constructeur
|> ptr->~OBJET(); // appel du destructeur
|> ptr->OBJET(); // appel du constructeur
|> Mais ça ne doit pas marcher. Il faut sans doute utiliser un
|> « placement new » : new(ptr) OBJET;
En effet. En fait, il est impossible à « appeler » le
constructeur ; il est toujours appelé implicitement, lors de
l'initialisation dans une définition, lors d'une expression de new,
ou lors d'une conversion de type. En revanche, ce dernier se ressemble
beaucoup à un appel explicit, surtout quand le constructeur n'a pas
de paramètres ou qu'il en a plus d'un. N'empêche que le
résultat, c'est toujours un nouvel objet, temporaire.
Fabien s'est trompé aussi en disant qu'il faut absolument appeler le
destructeur d'abord. Si le destructeur est trivial, on n'est pas
obligé à l'appeler, et quelque chose comme :
std::complex< double > z ;
// ...
new ( &z ) std::complex< double >( 1.0, 2.0 ) ;
est parfaitement légal (mais totalement sans intérêt).
--
James Kanze mailto:kanze@gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
|> Le samedi 11 octobre 2003 à 20:34:56, Alexandre a écrit dans |> fr.comp.lang.c++ :
|> >> Quand on a un pointeur sur un objet valide, on peut (je crois) |> >> appeler le destructeur, puis le constructeur. Mais bon, c'est de |> >> la sale bidouille -- je préfère ne jamais essayer ;-)
|> > Comme ça ?
|> > OBJET *ptr; |> > ptr = new OBJET ; // appel du constructeur |> > delete ptr; // appel du destructeur |> > ptr = new OBJET; // appel du constructeur
|> Non, plutôt comme ça :
|> OBJET *ptr; |> ptr = new OBJET ; // allocation+appel du constructeur |> ptr->~OBJET(); // appel du destructeur |> ptr->OBJET(); // appel du constructeur
|> Mais ça ne doit pas marcher. Il faut sans doute utiliser un |> « placement new » : new(ptr) OBJET;
En effet. En fait, il est impossible à « appeler » le constructeur ; il est toujours appelé implicitement, lors de l'initialisation dans une définition, lors d'une expression de new, ou lors d'une conversion de type. En revanche, ce dernier se ressemble beaucoup à un appel explicit, surtout quand le constructeur n'a pas de paramètres ou qu'il en a plus d'un. N'empêche que le résultat, c'est toujours un nouvel objet, temporaire.
Fabien s'est trompé aussi en disant qu'il faut absolument appeler le destructeur d'abord. Si le destructeur est trivial, on n'est pas obligé à l'appeler, et quelque chose comme :
std::complex< double > z ; // ... new ( &z ) std::complex< double >( 1.0, 2.0 ) ;
est parfaitement légal (mais totalement sans intérêt).
-- James Kanze mailto: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
James Kanze
Nicolas Aunai ç writes:
|> "Fabien LE LEZ" avait prétendu :
|> >> ma_classe c(c1); // instanciation de c a partir de c1
|> >> ma_classe cÁ;
|> > A noter que si c1 est du même type que c, alors les deux |> > écritures sont équivalentes.
|> ok, alors si j'avais eu par exemple :
|> class Entier |> { |> int i ; |> public : |> Entier(int j) |> { |> i=j ; |> return ; |> } |> } ;
|> et ensuite :
|> int j=2 ; |> Entier e1, e2=j ;
Erreur de compilation pour e1 ; Entier n'a pas de constructeur par défaut.
En ce qui concerne e2, formellement, le compilatuer « convertit » l'expression « j » en Entier, au moyen de Entier(int), puis appelle le constructeur de copie (ici, fournit implicitement) pour copier la valeur dans e2. La norme donne explicitement au compilateur le droit de supprimer la copie, en construisant directement dans e2 à partir de j, mais seulement à condition que le programme soit légal si le constructeur de copie avait réelement servi.
|> e1=j ;
Ici, il n'y a pas d'appel du constructeur, mais seulement de l'opérateur d'affectation (aussi fourni explicitement par le compilateur).
Pour que ce qui se passe soit plus clair, je suggèrerais d'écrire la classe avec tous les constructeurs explicits :
class Entier { public: Entier() : i( 0 ), id( ++ instanceId ) { std::cout << id << " : Constructeur par défaut appelén" ; } Entier( int j ) : i( j ), id( ++ instanceId ) { std::cout << id << " : Constructeur avec int appelén" ; } Entier( Entier const& other ) : i( other.i ), id( ++ instanceId ) { std::cout << id << " : Constructeur de copie appelén" ; } ~Entier() { std::cout << id << " : Destructeur appelén" ; } Entier& operator=( Entier const& other ) { i = other.i ; std::cout << id << " : Opérateur d'affectation appelén" ; return *this ; } private: int i ; int id ; static int instanceId ; } ; int Entier::instanceId = 0 ;
Ça vaut la peine d'expérimenter aussi avec de différents constructeurs déclarés privés -- comme j'ai dit ci-dessus, il y a des cas où le compilateur est obligé à pouvoir appeler un constructeur, sans qu'il soit obligé à l'appeler réelement.
Tu pourrais aussi expériementer avec d'autres cas où le constructeur et/ou l'opérateur d'affectation est appelé : avec par exemple une fonction qui prend un Entier en paramètre, ou qui renvoie un Entier. Quelque chose du genre :
Entier f( Entier i ) { std::cout << "Dans fn" ; return i ; }
int main() { Entier i ; Entier j = f( i ) ; i = f( j ) ; return 0 ; }
par exemple.
Toutefois, ne perd pas de vue que si de telles expériences peuvent aider à la compréhension, elles ne révèlent jamais que ce que fait un compilateur donné. À la fin, il faut bien vérifier les règles (et éventuellement essayer avec d'autres compilateurs), pour savoir quelles sont les libertés qu'a le compilateur.
-- James Kanze mailto: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
Nicolas Aunai <nicolas.aunai@virerça@free.fr> writes:
|> "Fabien LE LEZ" avait prétendu :
|> >> ma_classe c(c1); // instanciation de c a partir de c1
|> >> ma_classe cÁ;
|> > A noter que si c1 est du même type que c, alors les deux
|> > écritures sont équivalentes.
|> ok, alors si j'avais eu par exemple :
|> class Entier
|> {
|> int i ;
|> public :
|> Entier(int j)
|> {
|> i=j ;
|> return ;
|> }
|> } ;
|> et ensuite :
|> int j=2 ;
|> Entier e1, e2=j ;
Erreur de compilation pour e1 ; Entier n'a pas de constructeur par
défaut.
En ce qui concerne e2, formellement, le compilatuer « convertit »
l'expression « j » en Entier, au moyen de Entier(int), puis
appelle le constructeur de copie (ici, fournit implicitement) pour
copier la valeur dans e2. La norme donne explicitement au compilateur le
droit de supprimer la copie, en construisant directement dans e2 à
partir de j, mais seulement à condition que le programme soit
légal si le constructeur de copie avait réelement servi.
|> e1=j ;
Ici, il n'y a pas d'appel du constructeur, mais seulement de
l'opérateur d'affectation (aussi fourni explicitement par le
compilateur).
Pour que ce qui se passe soit plus clair, je suggèrerais d'écrire
la classe avec tous les constructeurs explicits :
class Entier
{
public:
Entier() : i( 0 ), id( ++ instanceId ) {
std::cout << id << " : Constructeur par défaut appelén" ;
}
Entier( int j ) : i( j ), id( ++ instanceId ) {
std::cout << id << " : Constructeur avec int appelén" ;
}
Entier( Entier const& other ) : i( other.i ), id( ++ instanceId ) {
std::cout << id << " : Constructeur de copie appelén" ;
}
~Entier() {
std::cout << id << " : Destructeur appelén" ;
}
Entier& operator=( Entier const& other ) {
i = other.i ;
std::cout << id << " : Opérateur d'affectation appelén" ;
return *this ;
}
private:
int i ;
int id ;
static int instanceId ;
} ;
int Entier::instanceId = 0 ;
Ça vaut la peine d'expérimenter aussi avec de différents
constructeurs déclarés privés -- comme j'ai dit ci-dessus, il y
a des cas où le compilateur est obligé à pouvoir appeler un
constructeur, sans qu'il soit obligé à l'appeler réelement.
Tu pourrais aussi expériementer avec d'autres cas où le
constructeur et/ou l'opérateur d'affectation est appelé : avec par
exemple une fonction qui prend un Entier en paramètre, ou qui renvoie
un Entier. Quelque chose du genre :
Entier
f( Entier i )
{
std::cout << "Dans fn" ;
return i ;
}
int
main()
{
Entier i ;
Entier j = f( i ) ;
i = f( j ) ;
return 0 ;
}
par exemple.
Toutefois, ne perd pas de vue que si de telles expériences peuvent
aider à la compréhension, elles ne révèlent jamais que ce
que fait un compilateur donné. À la fin, il faut bien vérifier
les règles (et éventuellement essayer avec d'autres compilateurs),
pour savoir quelles sont les libertés qu'a le compilateur.
--
James Kanze mailto:kanze@gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
|> >> ma_classe c(c1); // instanciation de c a partir de c1
|> >> ma_classe cÁ;
|> > A noter que si c1 est du même type que c, alors les deux |> > écritures sont équivalentes.
|> ok, alors si j'avais eu par exemple :
|> class Entier |> { |> int i ; |> public : |> Entier(int j) |> { |> i=j ; |> return ; |> } |> } ;
|> et ensuite :
|> int j=2 ; |> Entier e1, e2=j ;
Erreur de compilation pour e1 ; Entier n'a pas de constructeur par défaut.
En ce qui concerne e2, formellement, le compilatuer « convertit » l'expression « j » en Entier, au moyen de Entier(int), puis appelle le constructeur de copie (ici, fournit implicitement) pour copier la valeur dans e2. La norme donne explicitement au compilateur le droit de supprimer la copie, en construisant directement dans e2 à partir de j, mais seulement à condition que le programme soit légal si le constructeur de copie avait réelement servi.
|> e1=j ;
Ici, il n'y a pas d'appel du constructeur, mais seulement de l'opérateur d'affectation (aussi fourni explicitement par le compilateur).
Pour que ce qui se passe soit plus clair, je suggèrerais d'écrire la classe avec tous les constructeurs explicits :
class Entier { public: Entier() : i( 0 ), id( ++ instanceId ) { std::cout << id << " : Constructeur par défaut appelén" ; } Entier( int j ) : i( j ), id( ++ instanceId ) { std::cout << id << " : Constructeur avec int appelén" ; } Entier( Entier const& other ) : i( other.i ), id( ++ instanceId ) { std::cout << id << " : Constructeur de copie appelén" ; } ~Entier() { std::cout << id << " : Destructeur appelén" ; } Entier& operator=( Entier const& other ) { i = other.i ; std::cout << id << " : Opérateur d'affectation appelén" ; return *this ; } private: int i ; int id ; static int instanceId ; } ; int Entier::instanceId = 0 ;
Ça vaut la peine d'expérimenter aussi avec de différents constructeurs déclarés privés -- comme j'ai dit ci-dessus, il y a des cas où le compilateur est obligé à pouvoir appeler un constructeur, sans qu'il soit obligé à l'appeler réelement.
Tu pourrais aussi expériementer avec d'autres cas où le constructeur et/ou l'opérateur d'affectation est appelé : avec par exemple une fonction qui prend un Entier en paramètre, ou qui renvoie un Entier. Quelque chose du genre :
Entier f( Entier i ) { std::cout << "Dans fn" ; return i ; }
int main() { Entier i ; Entier j = f( i ) ; i = f( j ) ; return 0 ; }
par exemple.
Toutefois, ne perd pas de vue que si de telles expériences peuvent aider à la compréhension, elles ne révèlent jamais que ce que fait un compilateur donné. À la fin, il faut bien vérifier les règles (et éventuellement essayer avec d'autres compilateurs), pour savoir quelles sont les libertés qu'a le compilateur.
-- James Kanze mailto: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
Gabriel Dos Reis
James Kanze writes:
[...]
| Fabien s'est trompé aussi en disant qu'il faut absolument appeler le | destructeur d'abord. Si le destructeur est trivial, on n'est pas | obligé à l'appeler, et quelque chose comme : | | std::complex< double > z ; | // ... | new ( &z ) std::complex< double >( 1.0, 2.0 ) ; | | est parfaitement légal (mais totalement sans intérêt).
La norme ne décrit pas std::complex<double> comme ayant un destructeur trivial.
-- Gaby
James Kanze <kanze@alex.gabi-soft.fr> writes:
[...]
| Fabien s'est trompé aussi en disant qu'il faut absolument appeler le
| destructeur d'abord. Si le destructeur est trivial, on n'est pas
| obligé à l'appeler, et quelque chose comme :
|
| std::complex< double > z ;
| // ...
| new ( &z ) std::complex< double >( 1.0, 2.0 ) ;
|
| est parfaitement légal (mais totalement sans intérêt).
La norme ne décrit pas std::complex<double> comme ayant un destructeur
trivial.
| Fabien s'est trompé aussi en disant qu'il faut absolument appeler le | destructeur d'abord. Si le destructeur est trivial, on n'est pas | obligé à l'appeler, et quelque chose comme : | | std::complex< double > z ; | // ... | new ( &z ) std::complex< double >( 1.0, 2.0 ) ; | | est parfaitement légal (mais totalement sans intérêt).
La norme ne décrit pas std::complex<double> comme ayant un destructeur trivial.
-- Gaby
Alexandre
Objet& operator = (Objet& o) { this->~Objet(); this->Objet(o); ????? return *this; } C'est légal, ça ?
Mais encore une fois, c'est le genre de construction à ne jamais utiliser.