Question C++ Héritage
Dernière réponse : dans Programmation
Bonjour,
j'ai encore un problème ! Pour rappel (comme si il y avait des gens qui n'étaient pas au courant) je suis en train de programmer Warcraft 4 !
Mais bon, voilà mon problème : je gère mes petites unitées avec la classe Unite, et mes petits peons sont sur la classe Peon héritée de Unite. Mes peons ont en plus de Unite les variables ConstruitX et ConstruitY (position du batiment à construire) entre autres.
Mais voilà, pour dire a un peon de constuire bah je lui clique dessu, j'ai une fonction qui me donne un poiteur vers l'unitée sur laquelle je clique. Dans ce cas l'unitée et un peon, mais le pointeur et de type Unite (nous l'appelerons Toto).
C'est là que ca coince ! Si je dis Toto->ConstuitX=2; Bah ca repond : Olala ! No ConstruitX declarated in Unite mon petit gars !
Donc c'est embetant... Parceque faudrais que ma fonction qui gere le clique return directement un Peon, mais dans ce cas faut faire autant de fonctions que de type d'unite et c'est nul !
Donc je cherche un moyen pour à partir de mon pointeur Toto de type Unite arrivé à faire correspondre un pointeur de type Peon... C'est clair ?
En gros faut que Toto construise son batiment quoi !
Merci d'avance pour vos réponses par milliers, et entrainez vous bien car Warcraft 4 débarquera bientôt ! Surement. Peut être. On verra...
j'ai encore un problème ! Pour rappel (comme si il y avait des gens qui n'étaient pas au courant) je suis en train de programmer Warcraft 4 !
Mais bon, voilà mon problème : je gère mes petites unitées avec la classe Unite, et mes petits peons sont sur la classe Peon héritée de Unite. Mes peons ont en plus de Unite les variables ConstruitX et ConstruitY (position du batiment à construire) entre autres.
Mais voilà, pour dire a un peon de constuire bah je lui clique dessu, j'ai une fonction qui me donne un poiteur vers l'unitée sur laquelle je clique. Dans ce cas l'unitée et un peon, mais le pointeur et de type Unite (nous l'appelerons Toto).
C'est là que ca coince ! Si je dis Toto->ConstuitX=2; Bah ca repond : Olala ! No ConstruitX declarated in Unite mon petit gars !
Donc c'est embetant... Parceque faudrais que ma fonction qui gere le clique return directement un Peon, mais dans ce cas faut faire autant de fonctions que de type d'unite et c'est nul !
Donc je cherche un moyen pour à partir de mon pointeur Toto de type Unite arrivé à faire correspondre un pointeur de type Peon... C'est clair ?
En gros faut que Toto construise son batiment quoi !
Merci d'avance pour vos réponses par milliers, et entrainez vous bien car Warcraft 4 débarquera bientôt ! Surement. Peut être. On verra...
Autres pages sur : question heritage
Lassé par la pub ? Créez un compte
ha.. enfin une question interessante...
moi je vois plutot une méthode dans Unité qui renverrai le vrai type d'Unité (methode virtuelle pure donc) et en fonction de ca, faire le bon casting et donc appeler la bonne méthode...
par contre ca risque de devenir rapidement lourd
AMHA c'est l'objet lui meme qui doit pouvoir donner la liste de ses actions possible...
moi je vois plutot une méthode dans Unité qui renverrai le vrai type d'Unité (methode virtuelle pure donc) et en fonction de ca, faire le bon casting et donc appeler la bonne méthode...
par contre ca risque de devenir rapidement lourd
AMHA c'est l'objet lui meme qui doit pouvoir donner la liste de ses actions possible...
moi je verrais ca comme ca.
Tu peut utiliser le cast mais sans verification. Genre tu part du principe que si tu lance une construction c'est que tu as un peon ( le racourcis permettant une construction n'apparait qu'avec un peon ...) , et donc tu cast sans verification que cela soit possible. (la technique de Kangol te permet de verifier cela).
Pour la verification tu peut declarer des variables en define afin de pouvoir realiser ceci par exemple.
Tu peut utiliser le cast mais sans verification. Genre tu part du principe que si tu lance une construction c'est que tu as un peon ( le racourcis permettant une construction n'apparait qu'avec un peon ...) , et donc tu cast sans verification que cela soit possible. (la technique de Kangol te permet de verifier cela).
Pour la verification tu peut declarer des variables en define afin de pouvoir realiser ceci par exemple.
if ( toto.veriftype(PEON) )
{
(peon).tot.construire();
}
Citation :
moi je verrais ca comme ca.
if ( toto.veriftype(PEON) )
{
(peon).tot.construire();
}
En C++ moderne, tu n'as plus besoin de coder de fonction verifType() car le mécanisme est intégré au langage, ça se nomme le RTTI :
Peon * peon = dynamic_cast<Peon> (unite);
if (peon == null)
{
return; // ça n'est pas un péon
}
peon->build();
Bonjour tout le monde !
(C'est moi Podia-Your)
Merci beaucoup pour vos réponses, mais malgrès ça j'ai po réussit à dire a Toto de construire, bah oui pour faire des casting vos des trucs virtual, et ça c'est compliquer
Par contre j'ai posé la question à mon ancien prof de programmation et il m'a trouvé une solution merveilleuse et toute simple !
((Peon *) Toto)->ConstruitX = X;
c'est tout ! Et ça marche nikel
C'est quand même plus pratique que de faire un casting virtual abstract de la factory de mr Liskov's...
Voilà ça peux vous servir un jour.
Sinon je suis triste je me suis fait viré d'Unilog hier
C'est des gros méchants qui puent ! NAH ! En plus y sont po beau.
Mais bon c'est une bonne nouvelle comme ça Warcraft 4 sortira plus vite !
(C'est moi Podia-Your)
Merci beaucoup pour vos réponses, mais malgrès ça j'ai po réussit à dire a Toto de construire, bah oui pour faire des casting vos des trucs virtual, et ça c'est compliquer
Par contre j'ai posé la question à mon ancien prof de programmation et il m'a trouvé une solution merveilleuse et toute simple !
((Peon *) Toto)->ConstruitX = X;
c'est tout ! Et ça marche nikel
C'est quand même plus pratique que de faire un casting virtual abstract de la factory de mr Liskov's...Voilà ça peux vous servir un jour.
Sinon je suis triste je me suis fait viré d'Unilog hier
C'est des gros méchants qui puent ! NAH ! En plus y sont po beau.
Mais bon c'est une bonne nouvelle comme ça Warcraft 4 sortira plus vite !
Comme ca :
enfin dans le contexte, là ca return l'unite quon lui clique dessu, si c un peon on affiche un certain minimenu (avec icone pour choisir les action), si il clique sur un batiment a construire on fait ((Peon *) Kipose)->ConstruitX = X; et blabla... tout le reste...
Unite * ReturnCible(int X,int Y)
{
Unite *Courant;
Courant=PremierUnite; //PremierUnite est global.
while (Courant!=NULL)
{
if (Courant->X==X && Courant->Y==Y)
return Courant;
Courant=Courant->Suivant;
}
return NULL;
}
enfin dans le contexte, là ca return l'unite quon lui clique dessu, si c un peon on affiche un certain minimenu (avec icone pour choisir les action), si il clique sur un batiment a construire on fait ((Peon *) Kipose)->ConstruitX = X; et blabla... tout le reste...
Olala tu poses beacoup de questions
J'ai une variable globale KoakeSelect.
Dans la boucle du jeu j'apelle à chaque fois entre autres :
InfoSelect(void); //Renseigne KoakeSelect et NbSelect et d'autre trucs global.
MiniMenu(void); //Affiche le minimenu.
AfficheTexte(void); //Donne des infos dans un cadre comme dans War3.
Voilà quelques fonctions :
J'ai une variable globale KoakeSelect.
Dans la boucle du jeu j'apelle à chaque fois entre autres :
InfoSelect(void); //Renseigne KoakeSelect et NbSelect et d'autre trucs global.
MiniMenu(void); //Affiche le minimenu.
AfficheTexte(void); //Donne des infos dans un cadre comme dans War3.
Voilà quelques fonctions :
void InfoSelect(void)
{
int KeSelect;
Unite *Courant;
Batiment *BatimentCourant;
Courant=PremierUnite;
BatimentCourant=PremierBatiment;
NbUniteSelect=0;
KeSelect=0;
while (Courant!=NULL)
{
if (Courant->Select==1)
NbUniteSelect++;
if (Courant->Select==1 && KeSelect==0)
KeSelect=Courant->Type;//Le premier selectionné.
if (Courant->Select==1 && Courant->Type!=KeSelect)
KeSelect=-1;// =-1 si multi type.
Courant=Courant->Suivant;
}//Fin while parcours Unite.
while (BatimentCourant!=NULL)
{
if (BatimentCourant->Select==1 && KeSelect==0)
KeSelect=BatimentCourant->Type;//Le premier selectionné.
if (BatimentCourant->Select==1 && BatimentCourant->Type!=KeSelect)
KeSelect=-2;// =-2 si multi type.
BatimentCourant=BatimentCourant->Suivant;
}//Fin while parcours Bat.
KoakeSelect=KeSelect;// Ex : Vaut TypeGrunt si Select Only Grunt, 0 si rien, -1 si multi type, -2 si Bat.
}
void MiniMenu(void)
{
int i,j;
for (i=0;i<=1;i++)
for (j=0;j<=3;j++)
RemplitRectangle(400+j*36,356+i*36,32,32,0x555555);//Affiche le fond des cases.
if (KoakeSelect==TypePeon && NbUniteSelect==1 && PoseBatiment==0)
{
RemplitRectangle(400,356,32,32,0xAAAAAA);//Pour l'instant ya que un choix.
if (ChoixMiniMenu()==1)//Si on a cliquer sur une case. Voir en dessous...
{
PoseBatiment=TypeTownHall;
Kipose=OneUnitSelect();//TODO : si return NULL -> Plante !
}
}
if (KoakeSelect==TypeGrunt)
{
RemplitRectangle(400,356,32,32,0xAAFFAA);//Affiche un truc différent pour grunt. Pas de gestion du menu pour le moment.
}
}//Fin MiniMenu().
int ChoixMiniMenu(void) //Return le numéro la case du menu si on clique.
{
int i,j;
for (i=0;i<=1;i++)
for (j=0;j<=3;j++)
if (SourisInRect(400+j*36,356+i*36,32,32)==1 && InstantDownB1==1)
return i*4+j+1;
return 0;
}
void AfficheTexte(void) //Quelques explemples temp pour voir le fonctionnement.
{
if (KoakeSelect==0)
AfficherTexte("selectionnez un peon. appuez sur p pour un new peon ou g pour un new grunt. appuyez sur v pourafficher la vie.");
if (KoakeSelect==TypePeon && NbUniteSelect==1 && PoseBatiment==0)
AfficherTexte("cliquez sur le batiment du menu pour construir.");
if (KoakeSelect==TypePeon && NbUniteSelect==1 && PoseBatiment==TypeTownHall)
AfficherTexte("placez le townhall sur la carte.");
if (KoakeSelect==TypePeon && NbUniteSelect>1)
AfficherTexte("vous avez selectionne plusieurs peons");
if (KoakeSelect==TypeGrunt)
AfficherTexte("vous avez selectionne que des grunts");
if (KoakeSelect==TypeTownHall)
AfficherTexte("c la pour new grunt");
if (KoakeSelect==-1)
AfficherTexte("vous avez un mix unites");
if (KoakeSelect==-2)
AfficherTexte("vous avez un mix dont bat");
}
Bonjour j'ai un soucis d'héritages en c++.
Je voudrais faire un programe de gestion d'entreprise, je crée une classe abstraite Society dont divers classes devront dériver ici; juste Employed. Scociety me servirait pour construire un vecteur qui pourait contenir tout les élément d'une entreprise(employed, service, divison, ...).
Mais lorsque j'implémente de nouvelles méthodes dans ma classe Employed héritée de Society mon compilateur Borland C++ 5.5 me dit que ces methodes ne font pas parties de society.
voici mon prog :
ce code produit 3 erreur de compilation :
error 'SetName' is not a member of 'Society' in function main
error 'SetSurname' is not a member of 'Society' in function main
error 'Setdate' is not a member of 'Society' in function main
J'avoue être perdu et avoir chercher longtemps mais sans aucun resultat,
je pensais a un 'opérator=', mais il me semble que non vu que je joue avec des adresse.
Merci de bien vouloir m'aider. J'aprend le C++
mais je ne demande qu'a apprendre
merci d'avance.
Je voudrais faire un programe de gestion d'entreprise, je crée une classe abstraite Society dont divers classes devront dériver ici; juste Employed. Scociety me servirait pour construire un vecteur qui pourait contenir tout les élément d'une entreprise(employed, service, divison, ...).
Mais lorsque j'implémente de nouvelles méthodes dans ma classe Employed héritée de Society mon compilateur Borland C++ 5.5 me dit que ces methodes ne font pas parties de society.
voici mon prog :
//Society.h
class Society{
protected:
unsigned long id; //identifiant
unsigned long money; // budget
char *function; //fonction
public:
Society(void);
Society(unsigned long m, char *f);
virtual ~Society(void);
virtual void SetFunction(char *f);
virtual void Display(ostream& out);
virtual char* WhoIs(void)=0;
};
//Society.cpp
#include <iostream.h>
#include <string.h>
#include "Employed.h"
Society::Society(void){
id=0;
money=0;
function=new char[10];strcpy(function,"Undefined");
}
Society::Society(unsigned long m, char *f){
id=0;
money=m;
function=NULL;
SetFunction(f);
}
Society::~Society(void){
if(function!=NULL) delete [] function;
}
void Society::SetFunction(char *f){
if(function!=NULL) delete [] function;
function=NULL;
function=new char[strlen(f)+1];
if (function) strcpy (function, f);
}
void Society::Display(ostream& out){
out << "Fonction : " << function << endl;
out << "Identifiant : " << id << endl;
out << "Credit : " << money << endl;
}
//Employed.h
class Employed : public Society{
private:
static unsigned long id_empl;
protected:
unsigned long link;
char *name;
char *surname;
char *date;
public:
Employed(void);
Employed(unsigned long m, unsigned long l, char *f, char *n, char *s, char *d);
~Employed(void);
void SetName(char *n);
void SetSurname(char *s);
void SetDate(char *d);
void Display(ostream& out);
char* WhoIs(void);
};
//Employed.cpp
#include <iostream.h>
#include <string.h>
#include "Society.h"
#include "Employed.h"
unsigned long Employed::id_empl=0;
Employed::Employed(void):Society(){
link=0;
id=id_empl++;
name=new char[10];strcpy(name,"Undefined");
surname=new char[10];strcpy(surname,"Undefined");
date=new char[10];strcpy(date,"Undefined");
}
Employed::Employed(unsigned long m,unsigned long l, char *f, char *n, char *s, char *d):Society(m,f){
link=l;
id=id_empl++;
name=NULL;SetName(n);
surname=NULL;SetSurname(s);
date=NULL;SetDate(d);
}
Employed::~Employed(void){
if(name!=NULL) delete [] name;
if(surname!=NULL) delete [] surname;
if(date!=NULL) delete [] date;
}
void Employed::SetName(char *n){
if(name!=NULL) delete [] name;
name=NULL;
name=new char[strlen(n)+1];
if (name) strcpy (name, n);
}
void Employed::SetSurname(char *s){
if(surname!=NULL) delete [] surname;
surname=NULL;
surname=new char[strlen(s)+1];
if (surname) strcpy (surname, s);
}
void Employed::SetDate(char *d){
if(date!=NULL) delete [] date;
date=NULL;
date=new char[strlen(d)+1];
if (date) strcpy (date, d);
}
///Method Display
void Employed::Display(ostream& out){
Society::Display(out);
out << "Nom : " << name << endl;
out << "Prenom : " << surname << endl;
out << "Date d'embauche : " << date << endl;
out << "Service atachee : " << link << endl;
}
///Method WhoIs
char* Employed::WhoIs(void){
return ("EMPLOYED");
}
//Main.cpp
#include <iostream.h>
#include <conio.h>
#include "Society.h"
#include "Employed.h"
void main(void){
Society *pile[2];
p[0]=new Employed();
p[1]=new Employed();
p[0]->SetName('nobody');
p[0]->SetSurname('anybody');
p[0]->SetDate('00-00-00');
p[0]->Display(cout);
delete p[0];
delete p[1];
getch();
exit(0);
}
ce code produit 3 erreur de compilation :
error 'SetName' is not a member of 'Society' in function main
error 'SetSurname' is not a member of 'Society' in function main
error 'Setdate' is not a member of 'Society' in function main
J'avoue être perdu et avoir chercher longtemps mais sans aucun resultat,
je pensais a un 'opérator=', mais il me semble que non vu que je joue avec des adresse.
Merci de bien vouloir m'aider. J'aprend le C++
mais je ne demande qu'a apprendre
merci d'avance.
Society *pile[2];
p[0]=new Employed();
N'y-a-t'il pas un problème, entre pile et p ?
Si tu veux que p se comporte comme un objet de la classe Employed, il te suffit de le "caster" :
Society *p[2];
p[0]=new Employed();
Employed(p[0])->SetName('nobody');
[ Révise ton anglais aussi, société (entreprise) se dit company, et employé se dit employee
]
En effet j'ai fait une erreur en recopiant mon code sur le forum 'p' et 'pile' sont mélanger, mais dans mon main il ne le sont pas.Zeb ton conseille semblait être très interessant mais le complateurs me dit ceci maintenant :
could not find a match for Employed::Employed(Society *) in function main()
Je pense a des problèmes de constructeur par recopie et operator= dans mes classes.Mais le soucis est que en utilisant le cast ainsi je perd l'avantage de la virtualisation, qui me permet de concevoir un vecteur dans lequel je peux mettre indiférament diférentes classes hériter de Society
sinon mon anglais est pitoyable je sais merci quand même
Sinon pour mes biblio borland c++ ne tolère pas les include sans .h, #include <iostream> est invalide. Désoler je suis plus très standard avec mon c++ archaique.
Citation :
En effet j'ai fait une erreur en recopiant mon code sur le forum 'p' et 'pile' sont mélanger, mais dans mon main il ne le sont pas.Zeb ton conseille semblait être très interessant mais le complateurs me dit ceci maintenant :
could not find a match for Employed::Employed(Society *) in function main()
Je pense a des problèmes de constructeur par recopie et operator= dans mes classes.Mais le soucis est que en utilisant le cast ainsi je perd l'avantage de la virtualisation, qui me permet de concevoir un vecteur dans lequel je peux mettre indiférament diférentes classes hériter de Society
sinon mon anglais est pitoyable je sais merci quand même
Sinon pour mes biblio borland c++ ne tolère pas les include sans .h, #include <iostream> est invalide. Désoler je suis plus très standard avec mon c++ archaique.
1/ vu que tu appelles le constructeur qui n'existe pas, c'est logique qu'il gueule
2/ change de compilateur
Je viens de comprendre ma bourde! Il était évident que le pointeur Society *p[10]; dans lequel je stock des adresses de classe héritées comme Employed, pouvait résoudre des appellent de méthodes déclarées virtuel. Mais que les méthodes que j'implémente pour la première fois dans ma classe Employed ne sont pas connues par Society d'où le bug.J'ai mal compris l'idée d'édition de lien dynamique en C++ ou le compilateur résout l'appel de la méthode en fonction du type effectif de l'objet pointé; il ne peut résoudre l'appel que si la méthode a été déclarer virtuel dans la classe de base. J'ai raccroché ce point du C++ avec le Java ou la ligature des méthodes héritées est toujours dynamique; c'est quand même restrictif le C++ par rapport au java... Faut que j'arrête de vivre Java
Sinon pour le compil BorlandC ben il m'est imposé alors j'essaye de faire avec. Sinon KangOl bien d'accord avec toi GCC c'est le best des compil
Je tiens a vous remercier tous d'avoir consacrer un peu de temps au cancre d'étudiant que je suis et m'avoir aider pour mon travail sincèrement merci.
Lassé par la pub ? Créez un compte