Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Probleme sur un constructeur avec un parametre par defaut

24 réponses
Avatar
giova
bonjour

j'ai une classe Test avec (disons) un simple constructeur :

Test(int num=1)
{
cout<<"construceur : "<<num<<endl;
}

ensuite j'ai ceci dans mon main :

Test tata; //erreur a la compilation
Test toto();
Test titi(5);

Bon pour le probleme de tata je pense avoir compris : en créant le
constructeur a un parametre, on perd le constructeur par defaut, oui
mais c'est quand meme bizare, je vais y venir.

Mon probleme est que la ligne Test toto(); semble ne pas etre éxécutée.

j'utilise VC 2003 et lorsque je débug apres avoir placé un point d'arret
sur Test toto(); le programme se met en pause sur l'instruction
suivante, comme si Test toto(); ne comprennait aucune instruction.
j'ai égallement placé un point d'arret a l'interieur du constructeur,
pour etre sur de savoir quand il est lancé, or, seul Test titi(5) semble
l'appeller.
et pour finir dans le debuggeur "variable locales" seul titi apparait.

alors je ne comprends pas pourquoi Test toto() n'appelle pas le
constructeur avec un parametre par defaut ???
pourquoi la ligne semble ignorée sans qu'on m'avertisse de quoi que ce
soit lors la compil ou lors du debuggage? Je veux dire, soit le
compilateur me jete, soit le programme plante, soit il me construit
toto, mais la vraiment j'ai rien !!!

idem pour Test tata; pourquoi ne peut on pas "traduire" cette ligne par
Test tata(int num=1) soit => Test tata(1); ???

merci d'avance pour les lumieres que vous allez m'apporter.

4 réponses

1 2 3
Avatar
giova
Gabriel Dos Reis wrote:

"Jean-Noël Mégoz" writes:

[...]

| Soit une classe Classe, dont on définit 2 constructeurs ainsi :
| Classe::Classe(int i=0)
| {
| cout << "argument entier" << endl;
| }
| Classe::Classe(float f=0.0)
| {
| cout << "argument flottant" << endl;
| }
|
| Lors de l'instanciation :
| Classe objet;

C'est une déclaration de variable, mais il y a ambiguité pour le
constructeur à utiliser. Donc erreur.

-- Gaby


exactement, et c'est vraiment lié au fait que lors de l'instanciation,
le compilo est incapable (et c'est parfaitement logique) de savoir quel
constructeur appeller tout comme :

Soit une classe Classe, dont on définit 2 constructeurs ainsi :
| Classe::Classe()
| {
| cout << "argument entier" << endl;
| }
| Classe::Classe(float f=0.0)
| {
| cout << "argument flottant" << endl;
| }


aurait posé probleme pour la meme raison.

en revanche il en arait éété auterment avec un :

Soit une classe Classe, dont on définit 2 constructeurs ainsi :
| Classe::Classe(int x,int i =0)
| {
| cout << "argument entier" << endl;
| }
| Classe::Classe(float y, float f=0.0)
| {
| cout << "argument flottant" << endl;
| }


ici grace aux parametres x et y le compilo serait capable de savoir le
quel appeller, mais a mon avis faudrait explicitement caster le premier
param lors de l'instanciation :

Classe toto((int)1);
Classe titi((float)2);
Classe tata(2.0); //2.0 n'est pas un entier puisqu'a virgule donc pris
pour un float.

cette ligne a mon avis ne passerait pas :

Classe tutu(2);

car le compilo ne peut savoir si il s'agit d'un int ou d'un float.

Avatar
Jean-Noël Mégoz
"giova" a écrit dans le message de
news:40af1114$0$21564$
Gabriel Dos Reis wrote:

cette ligne a mon avis ne passerait pas :

Classe tutu(2);

car le compilo ne peut savoir si il s'agit d'un int ou d'un float.


AMHA, il n'y a pas de doute : le compilo prendra ça pour un int !
Chaque fois que le cas s'est présenté pour moi, " float f = 2; " générait un
warning, là ou " float f = 2.0;" passait sans problème (ou même " float f 2.; ").

Avatar
kanze
giova wrote in message
news:<40af1114$0$21564$...
Gabriel Dos Reis wrote:

Soit une classe Classe, dont on définit 2 constructeurs ainsi :
| Classe::Classe(int x,int i =0)
| {
| cout << "argument entier" << endl;
| }
| Classe::Classe(float y, float f=0.0)
| {
| cout << "argument flottant" << endl;
| }


ici grace aux parametres x et y le compilo serait capable de savoir le
quel appeller, mais a mon avis faudrait explicitement caster le
premier param lors de l'instanciation :

Classe toto((int)1);
Classe titi((float)2);
Classe tata(2.0); //2.0 n'est pas un entier puisqu'a virgule donc pris
pour un float.


Non. 2.0 n'est pas un float, c'est un double. On peut convertir un
double en float, de même qu'on peut convertir un double en int. C'est
donc ambigu.

Tu as violé une des règles de base de l'utilisation du surcharge sans
surprise : s'il y surcharge sur un type entier, il faut toujours en
avoir aussi sur int, et s'il y a surcharge sur un type flottant, il faut
toujours en mettre aussi pour double. Parce que sinon, tu risques fort
d'avoir ce genre d'ambiguïté ; les utilisateurs écrivent tout
naturellement 2.0, et non 2.0F, comme il faudrait.

cette ligne a mon avis ne passerait pas :

Classe tutu(2);

car le compilo ne peut savoir si il s'agit d'un int ou d'un float.


Pourquoi non ? L'expression 2 a type int. Toujours. Il peut se convertir
en float, si un int ne peut pas servir, mais il a type int. Une
expression a toujours un type (et un seul) bien défini.

Il y a eu un peu de laisser aller dans le langage dans ce thread. Des
exprssions du genre « le compilateur interprète ça comme une déclaration
de fonction », par exemple, quand ce qu'il faut dire, c'est que c'est
une déclaration de fonction. Ce n'est pas une question d'interprétation
du compilateur. De même, une expression a toujours exactement un type,
int, ou double, ou float. Et c'est le type de l'expression qui sert dans
la résolution du surcharge. Donc, « Classe tutu(2) » passe bien, parce
que le type de l'expression « 2 » est int, qui correspond exactement à
une des fonctions. Tandis que « Classe tata( 2.0 ) » ne passe pas, parce
que 2.0 a type double, il n'y a pas de constructeur qui prend un double,
et la conversion double en float est considérée aussi bien que double en
int.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Gabriel Dos Reis
writes:

[...]

| Il y a eu un peu de laisser aller dans le langage dans ce thread. Des
| exprssions du genre « le compilateur interprète ça comme une déclaration
| de fonction », par exemple, quand ce qu'il faut dire, c'est que c'est
| une déclaration de fonction. Ce n'est pas une question d'interprétation
| du compilateur.

L'ambiguité de la grammaire C++ dont il est question, suppose un
« tentative parsing ». Je ne vois donc pas de problème particulier
avec l'utilisation de « interpretation », si les gens comprennent.

-- Gaby
1 2 3