Bonjour,
Supposons que j'ai définit une classe "demo" avec des constructeurs par défaut et de copie .
Quelle est la différence exacte entre ces deux déclarations : ( en ce qui conserne l'appel des constructeurs )
1- demo b(5);
2- demo b = 5; ?
Merci![]()
Bonjour,
Supposons que j'ai définit une classe "demo" avec des constructeurs par défaut et de copie .
Quelle est la différence exacte entre ces deux déclarations : ( en ce qui conserne l'appel des constructeurs )
1- demo b(5);
2- demo b = 5; ?
Merci![]()
Bonjour,
La signigication des syntaxes est légèrement différente :
Dans le cas 1, l'on cherche à créer un U à partir d'un T. Pour réaliser ceci, il y a deux solutions :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 T t; //1 U u1(t); //2 U u2 = t;
-> Un constructeur (éventuellement explicite) :
Dans ce cas il faut que t soit convertible vers V (V peut être un type complexe).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 U::U(V v);
-> Un operateur de conversion (éventuellement explicite), de la forme :
Dans le cas 2, l'on cherche à convertir un T vers un U. Pour réaliser ceci, il y a deux solutions :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 T::operator U();
-> Un constructeur non-explicit de la forme
-> Un opérateur de convertion non-explicite de la forne
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 U::U(cv T&);
Tu peux donc voir que la seule (*) différence se situe au niveau de la forme des constructeurs (**) (et à la possibilité d'utiliser "explicit"). Ainsi prenons ce code :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 T::operator U();
Voila les comportements qu'on doit observer :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 struct B; struct C; struct A { //1 // operator B(); //2 // operator C(); }; struct B { //3 // B(const A&){} }; //1 //A::operator B() //{ return B(); } struct C { //4 // C(const B&){} //5 // C(const A&){} }; //2 //A::operator C() //{ return C(); } int main() { A a; //6 // C c1(a); //7 // C c2 = a; }
-> On décommente 1 et 4, dans ce cas 6 compile mais 7 ne compile pas.
-> On décommente 2, dans ce cas 6 et 7 compilent.
-> On décommente 3 et 4, dans ce cas 6 compile mais 7 ne compile pas.
-> On décommente 5, dans ce cas 6 et 7 compilent.
On voit donc que les lignes 1 et 3 peuvent servir dans le même but : convertir un objet en un autre, de même pour les lignes 2 et 5 : construire et convertir. Et on voit aussi que la légère différence de signification des deux syntaxes 5 et 6 peut se faire ressentir : construire ou convertir n'est pas exactement la même chose.
(*) Il y en a peut-être d'autres, mais elles restent marginales, AMA.
(**) La raison de ceci est que les conversions implicite définient par l'utilisateur ne peuvent pas s'enchainer.
Partager