[C++] Problème avec les classes

Problème avec les classes [C++] - Programmation

Marsh Posté le 05-02-2001 à 20:14:11    

Salut, here a part of my bugged code :) :
 
#include <iostream.h>
 
class Date{
ssprivate :
ssssint jour,
ssssssssmois,ssssssssssannee;
sspublic :
ssssDate(int prmJour = 1, int prmMois = 1, int prmAnnee = 1980) ;
ssss~Date();
} ;
 
class Personne{
ssprivate :
ssssDate dateNai ;
sspublic :
ssssPersonne(Date prmDateNai = (1, 1, 1980)) ;
} ;
 
Date::Date(int prmJour, int prmMois, int prmAnnee){
ssjour = prmJour ;
ssmois = prmMois ;
ssannee = prmAnnee ;
sscout << "Création : " << this << endl ;
}
 
Date::~Date(){
sscout << "Destruction : " << this << endl ;
}
 
Personne::Personne(Date prmDateNai){
ssdateNai = prmDateNai ;
}
 
void main(){
ssPersonne p ;
ssPersonne z(10);
}
 
Ligne Personne p : va dans Personne::Personne mais comme y'a un param. de type Date, saute tt de suite dans Date::Date et là, prmJour vaut 1980 alors qu'à priori il devrait valoir 1 d'après le proto de la fonction membre Date ....
Voilà, c'est cette erreur que je capte pas ...
 
Ensuite quand je crée dateNai, la ça marche, j'ai bien 1/1/1980 mais comme cette valeur est écrasée par prmDateNai qui contient 1980/1/1980, ça marche pas...
Et pour la personne z, pas de pb !
 
Si vous pouviez me donner 1 p'ti coup de pouce .. ce serait sympa (j'ai déjà demandé à 1 de mes profs et y'a pas trouvé...)

Reply

Marsh Posté le 05-02-2001 à 20:14:11   

Reply

Marsh Posté le 05-02-2001 à 20:39:18    

Curieux en effet...ss:confused:
 
Ce que je trouve encore plus bizarre, c'est que si tu mets :
 
ss Personne(Date prmDateNai = (2, 2, 1980));
 
en constructeur de Personne, il prend toujours la date "1980/1/1980"...

Reply

Marsh Posté le 05-02-2001 à 20:49:17    

Tres simpless
 
Personne(Date prmDateNai = Date(1,1,1980)) ;

Reply

Marsh Posté le 05-02-2001 à 20:58:43    

J'avoue que j'ai quand même été surpris que tu puisses, comme cela, initialiser les champs privés de Date dans la classe Personne, alors que cette dernière n'est pas friend.
Mon première réflexe aurait été de dire "Ce n'est pas trop joli-joli tout ça... Crée plutôt un champ const statique "Date:: DEFAUT" qui contiendrait cette date par défaut".
 
Et ben, comme par hasard, de faire ça, ça résoud ton problème.
 
Je m'explique. Si tu déclare une variable locale comme suit:
    Date   maDate = (1, 1, 1981);
date vaut (jour=1981, mois=1, annee=1980). Rigolo, c'est vrai, mais pendant un temps limité seulement... :rolleyes: ;)
 
Par contre, si tu la déclares ainsi:
    Date   maDate (1, 1, 1981);
date vaut (jour=1, mois=1, annee=1980). :benetton:
 
Bref, c'est le '=' qui est la cause du problème.
 
Donc déclare ceci dans ta classe Date:
    static const Date DEFAULT;
 
Puis ceci, accompagnant le constructeur et le destructeur de Date:
    const Date Date:: DEFAULT(1, 1, 1980);
 
Et tu pourras écrire, dans la class Personne:
    Personne(Date prmDateNai = Date:: DEFAULT) ;
 
Et ton programme marchera comme il faut.  :sol:

 

--Message édité par BifaceMcLeOD--

Reply

Marsh Posté le 05-02-2001 à 21:29:15    

BifaceMcLeOD a écrit a écrit :

Curieux en effet...  :confused:
 
Ce que je trouve encore plus bizarre, c'est que si tu mets :
 
   Personne(Date prmDateNai = (2, 2, 1980));
 
en constructeur de Personne, il prend toujours la date "1980/1/1980"...

 





 
Je sais : au début j'avais mis seulement
 
Personne(Date prmDateNai) ; pensant que le compilo verrait que pour un objet de type Date, il n'y a pas besoin de paramètres mais ça marchait pas donc j'ai rajouté "=(1,1,1980)" en param. par défaut
 
Je compile sous Borland C++ 4.52 (16bits easywin), peut-être qu'avec d'autre compilos j'aurais pus utiliser la 1ere version....

Reply

Marsh Posté le 05-02-2001 à 21:39:03    

Ce qui est rassurant, c'est que j'utilise gcc 2.95.2, et on obtient le même comportement... :)

 

--Message édité par BifaceMcLeOD--

Reply

Marsh Posté le 05-02-2001 à 22:12:52    

BifaceMcLeOD a écrit a écrit :

Ce qui est rassurant, c'est que j'utilise gcc 2.95.2, et on obtient le même comportement... :)
 
--Message édité par BifaceMcLeOD--

 





 
j'avais dit ça au cas ou.....

Reply

Marsh Posté le 05-02-2001 à 22:13:23    

J'ai essayé la soluce de xilebo et ça marche bien par contre ce que je comprends pas c'est qu'il n'appelle que 2 constructeurs alors que je pensais qu'il en aurait appellé 3 :
 
1 pour Date prmDateNai
1 pour Date(1,1,1980)
1 pour Date dateNai (de la classe Personne)
 
en fait les 2 premiers se font en 1 mais j'ai pas trop capté pquoi !
1 p'tite explication serait la bienvenue...
 
BifaceMcLeOD : j'ai essayé aussi ta soluce mais ça bug :
 
j'ai pas le droit de mettre const Date Date:: DEFAULT(1, 1, 1980); dans le constructeur sinon il me fait une belle GPF, normal y'arrète pas de créer des objets Date...
Pour que ça marche, il faut init. les attributs statiques en dehors après la déclaration de la classe par ex. ... a part ça, le code marche aussi
 
1 grand merci à tous les 2 !

Reply

Marsh Posté le 06-02-2001 à 01:29:18    

Et si tu remplaces la déclaration et la définition du contructeur de Personne par:
 
Personne(Date prmDateNai = Date(1, 1, 1980)):dateNai(prmDateNai){}  
 
ton constructeur ne sera plus appelé qu'une fois je crois.
 
En fait il existe un autre constructeur de Date, c'est le contructeur par copie:
Date(const Date&)  
qui est généré par le compilateur comme tu ne le fournis pas et est appelé pour les constructions de Date à partir de Date.

Reply

Marsh Posté le 06-02-2001 à 02:17:32    

*Syl* a écrit a écrit :

BifaceMcLeOD : j'ai essayé aussi ta soluce mais ça bug :
 
j'ai pas le droit de mettre const Date Date:: DEFAULT(1, 1, 1980); dans le constructeur sinon il me fait une belle GPF, normal y'arrète pas de créer des objets Date...
Pour que ça marche, il faut init. les attributs statiques en dehors après la déclaration de la classe par ex. ... a part ça, le code marche aussi




Je suis au courant qu'il faut définir un membre statique de classe ailleurs que là où il est déclaré. Quand je disais "accompagnant le constructeur et le destructeur de Date", je voulais dire "à côté de leur implémentation":
 
    Date:: Date(int prmJour, int prmMois, int prmAnnee) {
        ...
    }
 
    Date::~Date() {
        ...
    }
 
    const Date Date:: DEFAULT(1, 1, 1980);  
 
Et avant de te le donner, je l'ai compilé et testé chez moi...  :sarcastic:

Reply

Marsh Posté le 06-02-2001 à 02:17:32   

Reply

Marsh Posté le 13-02-2001 à 01:30:16    

petite explication de ce qui se passe quand on fait un truc du genre
 
class shit
{
 int a,b;
public:
 shit(a=0,b=0);
};
 
une expression du type (X,Y) évalue dans l'ordre X puis Y.
si ce sont des fonctions, elles sont appelées, si ce sont des variables, elles sont posées.
donc un truc du genre
int u=0;
u=(3,4);
...là u vaut le denier truc évalué entre les parenthèses, en l'occurrence 4
u=(u++,u+2);
..là u vaut 7 :)
 
donc quand je fais
shit s=(7,6);
c'est comme si je faisais
shit s=6;
et le compilo a un constructeur de shit avec 1 param int, le deuxième étant pris par défaut à 0
donc ce serait comme écrire
shit s(6,0);
voici l'explication
donc ne JAMAIS faire un truc du genre instanceclassemachin=(a,b,c)
sauf si c'est vraiment ce qu'on veut faire. et encore on risque d'introduire la confusion chez une personne qui relit le code

Reply

Marsh Posté le 13-02-2001 à 02:41:39    

On peut aussi s'amuser à surcharger l'opérateur "," :)

Reply

Sujets relatifs:

Leave a Replay

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