--------------------------------------------------
Objet: [IFT1166] Modifications au TP3
Date: Mon, 06 Dec 1999 20:38:08 -0500
De: Mohamed Lokbani <lokbani@IRO.UMontreal.CA>
A: gift1166@IRO.UMontreal.CA
--------------------------------------------------
Objet: [IFT1166] TP3 Suggestion & Q-R
Date: Fri, 03 Dec 1999 19:41:29 -0500
De: Mohamed Lokbani <lokbani@IRO.UMontreal.CA>
A: gift1166@IRO.UMontreal.CA
--------------------------------------------------
Subject: [IFT1166] Questions/Reponses TP3
Date: Fri, 19 Nov 1999 19:16:52 -0500
From: Mohamed Lokbani <lokbani@IRO.UMontreal.CA>
To: gift1166@IRO.UMontreal.CA
--------------------------------------------------
=======================================================================================
Objet: [IFT1166] Modifications
au TP3
Date: Mon, 06 Dec 1999 20:38:08 -0500
De: Mohamed Lokbani <lokbani@IRO.UMontreal.CA>
A: gift1166@IRO.UMontreal.CA
--------------------------------------------------
Bonjour,
Comme deja mentionne ds mes precedents emails (y compris sur l'enonce):
"Il ne vous est pas demandé de suivre cette déclaration
à la lettre, vous pouvez en
particulier ajouter ou retirer des membres. Seules les fonctionnalités
offertes dans la
déclaration doivent être respectées."
-1-
ceux/celles qui ont toujours des problemes pour surmonter l'erreur
tmp/cclDqHdt.o(.text+0x0): multiple definition of ......
peuvent remettre en plus des fichiers specifies, le fichier liste.cpp.
le fichier liste.cpp ne doit pas contenir les fonctions templates. (elles
doivent etre
dans un .h, c'est une directive du standard Ansi-C++).
vous pouvez inclure les methodes de classe Node<char *> dont le cas
ou
vous avez cree une classe Node<char *>, sinon la surdefinition de
certaines
methodes de la classe template Node<T> pour le traitement du <char
*>
ce n'est pas parce que vous avez la possibilite d'utiliser liste.cpp
que vous allez toute
de suite recourir a ce fichier pour mettre toutes les fonctions qui
poseraient problemes.
Faites le menage, et en cas de necessite, utilisez liste.cpp!
-2-
dans le main.cpp partie CLISTE:
Si vous voulez montrer les choses a ne pas faire, en voila une .....
la ligne 129:
liste[2] = "marche"; // un peu dangereux non ?
la reponse est oui! C'est dangereux! Assez souvent des problemes
sont causes par ce type d'affectation dans le cas ou le = n'est pas
defini
de facon appropriee.
il y a une solution pour contourner ce danger ..... une definition correcte
de l'operateur
d'affectation.
Pour ceux/celles qui ont du mal a s'affranchir du "Segmentation fault
(core dumped)"
vous pouvez mettre cette ligne en commentaire et faire la suite du
tp, et y revenir plus
tard a tete reposee. Le Segmentation Fault est genere lors de la desallocation
de la memoire.
Si vous avez prevu une fonction pour recuperer de la memoire, et si
vous avez mal code
votre programme, vous auriez eu cette erreur. Sinon ca aurait ete transparent,
et vous ne
seriez meme pas rendu compte que votre programme comportait un bug
....
Mohamed Lokbani.
=======================================================================================
Objet: [IFT1166] TP3 Suggestion & Q-R
Date: Fri, 03 Dec 1999 19:41:29 -0500
De: Mohamed Lokbani <lokbani@IRO.UMontreal.CA>
A: gift1166@IRO.UMontreal.CA
Bonjour,
ci-joint une suggestion a propos de la question 2.1.2 puis une reponse
a
une question a propos du tp3.
la remise a ete fixee pour le Jeudi 09 Decembre Minuit.
Mohamed Lokbani.
Suggestion
----------
La question de la section: 2.1
-2- Écrire le code nécessaire pour traiter le cas d'un
noeud du type <char
*>.
+++++++++
il est certainement preferable de ne specialiser que le constructeur
de la classe Node (de meme que le destructeur). A titre d'exemple voici
la syntaxe pour le constructeur :
Node<char *>::Node(char *e,Node<char *> *pnext)
{
// votre code
}
Sinon dans le cas ou vous souhaitez tout de meme specialiser la classe
Node dans sa globalite, il faut (au moins sur le compilateur qui est
a
votre disposition) que les fonctions non membres qui sont specialisees
soient definies dans un .cpp: ce ne sont plus des declarations. Si
vous
ne faites pas ca, le linker inclura une fois le code de la fonction
en
compilant professeur.cpp et une fois en compilant etudiant.cpp , d'ou
le message indiquant une redefinition...
un simple exemple:
dans le fichier a.h
#ifndef _a_
#define _a_
#include <iostream.h>
class a {
public:
friend void ma_fct();
};
void ma_fct(){}
#endif
dans le fichier b.cpp, uniquement cette ligne:
#include "a.h"
puis compilez le fichier b.cpp
gcc -Wall -c b.cpp
(ok).
dans le fichier c.cpp, uniquement cette ligne:
#include "a.h"
puis compilez le fichier c.cpp
gcc -Wall -c c.cpp
(ok).
dans le fichier test.cpp, un code juste pour pouvoir
realiser l'edition de liens:
#include "iostream.h"
int main() {
return 0;
}
puis vous compilez avec la commande:
g++ -Wall b.cpp c.cpp test.cpp
vous allez obtenir ce qui suit:
/tmp/ccstL7Fa.o: In function `ma_fct(void)':
/tmp/ccstL7Fa.o(.text+0x0): multiple definition of `ma_fct(void)'
/tmp/ccqpSCCr.o(.text+0x0): first defined here
collect2: ld returned 1 exit status
ma_fct a ete definie a partir de b.cpp (a cause de l'include a.h)
et a ete aussi definie mais cette fois-ci a partir de c.cpp (a cause
aussi de l'include a.h).
lors de l'edition de liens, le compilateur va retrouver une
double definition de 'ma_fct()' d'ou l'erreur.
____________________________________________________________________
Question
--------
>>j'ai une question pour vous au sujet de Cours.cpp
>>et Cours.h: dans la class Cours faut-il declarer
>>une liste de pointeur sur la liste des Professeurs
>>et une sur la liste des etudiants ou bien il faut
>>creer une autre liste d'etudiants et une autre liste
>>de professeur?
>>Pour l'instant j'ai pris l'option # 1 soit une liste
>>de pointeur qui pointe vers la liste des profs et une
>>autre qui pointe vers la liste d'etudiants.
>>Voici mon probleme:
>>Dans ma classe Cours je declare une liste de pointeurs
>>sur les Professeurs ainsi que une sur les etudiants:
>>PROTECTED:
>> List<Professeur*> liste_professeur;
>> List<Etudiant*> liste_etudiant;
>>Tout va bien lors de la compilation, parcontre certaines
>>erreurs apparaissent lors du "linking". Voici les erreurs
>>que l'on me donne:
>>Cours.obj : error LNK2001: unresolved external symbol
>>"public: __thiscall List<class Professeur *>::~List<class
>>Professeur *>(void)" (??1?$List@PAVProfesseur@@@@QAE@XZ)
>>Debug/Liste.exe : fatal error LNK1120: 4 unresolved externals
>>Quelle est le probleme?
Professeur est une classe. Tu vas instancier un objet pf du type
professeur. Cet objet tu vas l'inserer dans ta liste. Donc ta liste
doit contenir une liste d'objets pas une liste d'objets pointes.
regardes le main.cpp que j'ai joint au tp3:
au debut du main qui traite sur l'heritage (ligne: 136) il y a cette
ligne:
List<Etudiant> lst_etud;
de meme pour professeur ...
List<Professeur> lst_prof;
a aucun moment j'ai mis un pointeur.
ceci ecrit, la question a propos du "char *" peut-etre soulevee:
par exemple pourquoi ecrire : List<char *> ?
car la tu accedes a un tableau de caracteres. Une maniere d'acceder
a ce tableau est de passer par le pointeur de son premier element.
D'ou la necessite dans ce cas du "char *".
=======================================================================================
Subject: [IFT1166] Questions/Reponses TP3
Date: Fri, 19 Nov 1999 19:16:52 -0500
From: Mohamed Lokbani <lokbani@IRO.UMontreal.CA>
To: gift1166@IRO.UMontreal.CA
--------------------------------------------------
Bonjour,
Question -1-
-------------
>>>Pour l'exemple ci-dessous (tirée de la démo 7), j'ai
remarqué que le
>>>constructeur du patron de classe Note<T> est private!
>>>Est-ce normal??
par ta question si tu voulais dire s'il y a erreur, la reponse est non!
Tu
as la une autre
facon d'ecrire du C++. Cette ecriture montre le role que tu veux donner
a ta
classe
"Node" qui dans notre exemple ne sert que "List".
>>>Si oui, comment un constructeur qui est private puisse t-il être
utilisé???
extrait de liste.h
----------------
friend class List<T>;
// List peut acceder aux
champs prives de Node
c'est a partir de la classe liste qui a ete declaree amie. C'est a elle
de
manipuler "Node".
Si cette ecriture te derange, tu peux toi-meme definir ta classe List.
Comme
je l'ai deja mentionne
au cours, ce que nous vous demandons: c'est de garder les fonctionnalites
offertes, exemple:
remove_head
insert_end
etc.
pour que ca puisse fonctionner avec le main donne dans l'enonce du tp3.
++++++++++++++++
Question -2-
-------------
> Avant de me lancer dans le TP3, je veux etre sur de bien comprendre
les
> demos qui s'y rapportenr..
> Que signifie ceci, dans la demo 7:
>
> T* Head() const {return (first)? &(first->elt):NULL;} //
retourne l'elt
> first
> T* End() const {return (last)? &(last->elt):NULL;}
// retourne l'elt
> last
>
> Je comprends bien ce que font ces fonctions, mais c'est le (first)?
ou
> le (last)? qui m'echappent...
First et last sont des pointeurs respectifs sur le premier maillon et
le
dernier maillon de la liste chainee:
Node<T> * first;
// pointeur sur le premier elt de la liste
Node<T> * last;
// pointeur sur le dernier elt de la liste
return (first)? &(first->elt):NULL; est un raccourci pour :
if (first == NULL) return NULL;
return &(first->elt);
C'est tres courant/pratique en C/C++.
Ca marche ici car first s'il n'est pas NULL possede une valeur
differente de 0 (l'adresse d'une elt pointe) et en C, tout ce qui n'est
pas 0 est vrai (NULL est defini a 0 dans une librairie du genre
stdlib.h).
Bon courage.
Philippe.
++++++++++++++++
Mohamed Lokbani.
TOPQUESTION
=======================================================================================