Salut, j'ai quelques question en POO, et j'aimerais que vous m'aidiez si possible.
Voici l'objet ainsi que son implémentation:
.h : http://s4.noelshack.com/old/up/h-89a6351756.png
.cpp: http://s4.noelshack.com/old/up/cpp-6e5676a189.png
Alors voici, je me pose certaine question car je crois ne pas avoir compris le fonctionne de la poo comme il se doit...
Premièrement, Dans mon main, après avoir inclus Character.h, si je fais seulement:
Character test();
Cela devrait logiquement créer la classe?...
Donc après, je peux donc utiliser la fonction suivante sans erreur?(dans mon main):
test.go_right();
Car je ne sais pas pourquoi, mais j’obtiens dans un code tout simple une erreur ressemblant à ceci: error: request for member 'go_right' in 'perso', which is of non-class type 'Character()'|
Je ne comprends pas vraiment, alors j'espère avoir été assez claire pour que vous pussiez comprendre mes questions. Merci
" Premièrement, Dans mon main, après avoir inclus Character.h, si je fais seulement:
Character test();
Cela devrait logiquement créer la classe?...
Donc après, je peux donc utiliser la fonction suivante sans erreur?(dans mon main):
test.go_right(); "
Oui. ![]()
Et bien, très étrange, car après, je ne peux utiliser les fonctions de la classe créer....
Mon IDE est peut-être mal configuré?....
Merci de ta réponse.
Je pense que le problème vient des parenthèses lors de la déclaration en fait, essaye sans :
Character test;
Le constructeur par défaut sera appelé de toute façon.
Pocolo, je te remercie.
J'imagine que ce bug provenait du fait que mon constructeur était vide?
Merci beaucoup.
Le fait qu'il soit vide ou non ne change rien, c'est plutôt au niveau des arguments qu'il prend.
En général si ton constructeur ne prend aucun argument tu ne mets pas de parenthèses lorsque tu déclares une nouvelle instance de la classe en question.
Si ton constructeur prenait un int comme argument par exemple tu aurais pu (et même dû) écrire un truc du genre :
Character test(8);
D'accord merci beaucoup.
Quand tu mets les parenthese, le compilateur interprete ca comme une fonction qui ne prends pas d'argument et retourne un Character
Prends des bonnes habitudes aussi, genre fais plutôt:
Character* pTest = new Character();
pTest->go_right();
Parce que manipuler la classe comme objet directement, ce n'est pas très propre je trouve.
PS: Ceci est mon premier message sur ce forum ![]()
Pourquoi ce n'est pas propre Foudre ?
PS : Dans l'implémentation de ta classe je pense qu'il va y avoir un problème avec la compilation de la méthode go_left si j'ai bien lu ton .h ![]()
Je suis pas d'accord avec toi Foudre...on dirait que tu sous entend qu'il faut toujours déclarer les objets comme des pointeur?
Si tu fais ça ds ton code tu dois avoir à gérer des new/delete dans chacune de tes fonctions et cela ne doit pas rendre ton code plus "propre" pour autant.
Avec un new on va dire que tu alloue un espace dans la mémoire de la taille de ta classe et c'est à toi de penser à le supprimer avec un "delete" sinon cet espace sera considéré "occupé" en permanence.
Par contre si tu déclare une variable dans une fonction directement c'est sur la pile que cet element existe et donc il va disparaître de lui même lorsque l'on quitte la fonction.
L'utilisation de pointeur doit avoir un but,comme par exemple garder un lien vers une classe dans une autre.
ex: Mettons son Character peut avoir un moyen de locomotion et plusieurs Character peuvent utiliser le même vehicule tu peux faire un trucs genre
class Character
{
public:
void setVehicule(Vehicule* _vehPtr){m_vehicule = _vehPtr;}
private:
Vehicule* m_vehicule;
};
main()
{
Character c1,c2;
Vehicule veh;
c1.setVehicule(&veh);
c2.setVehicule(&veh);
}
Apres de cette façon si tu appliques un changement sur vehicule (disons par exemple changer la couleur) et bien ça sera "transparent" pour c1 et c2 puisqu'ils utilisent le même au final.
Tout ça pour dire que dans le cas de dragone169 ce n'est vraiment pas utile d'avoir un pointeur cela ne ferais que surcharger son code pour rien et donc ça ne serait pas plus propre, au contraire.
Dsl pour le long message, me suis un peu laisser emporter dans mes explications ^^
« Premièrement, Dans mon main, après avoir inclus Character.h, si je fais seulement:
Character test();
Cela devrait logiquement créer la classe? »
non !
C'est le fait d'include ton fichier Character.h (NB: on utilise plus volontier l'extension .hpp pour du C++) qui *définit* ta classe. Une classe, c'est juste un nom auquel on associe des opérations (les méthodes). Mais ça ne produit aucun code concret.
Faire « Character test; » en revanche, ça crée un *objet* de type Character, qu'on pourra manipuler à l'aide des méthodes décrites dans la déclaration de la classe Character.
NB: il ne faut effectivement pas mettre de paranthèses après test. C'est un peu tordu, je vous l'accorde, mais c'est comme ça. La raison est d'ailleurs la suivante : il faut que la syntaxe colle si on met (disons) "int" à la place de Character. Et là, on sait bien que "int i;" est valide, "int i(1);" aussi, mais pas "int i();".
« Prends des bonnes habitudes aussi, genre fais plutôt:
Character* pTest = new Character();
pTest->go_right(); »
tout faux. Mettre des pointeurs, ça ce n'est pas propre : la preuve, tu as oublié le new dans ton bout de code./
Et si ce sont les copies inutiles au niveau des appels de fonctions qui te font peur, pars réviser le passage d'arguments par référence (ainsi que la notion de const correctness dans la foulée, c'est pas directement lié, mais c'est tout aussi crucial).
s/new/delete/ ![]()
Nevdelothion
Tu n'as pas tort je dis pas ça, c'est vrai après que c'est sujet à débat.
Disons simplement que je suis habitué a programmer dans des SDK ou tu as par exemple pour faire simple une grand fonction Init() et une fonction Destroy(), dans ce cas la tu vois peut être ou je veux en venir?
Passage d'arguments par réference, oui je vois ce que tu veux dire, en fait c'est pareil que ce que il a été dit dit aussi, c'est vrai que j'ai l'habitude de faire entre plusieurs fonctions, et que pour moi faire un new c'est l'assurance que l'object existe tant que le delete n'a pas été fait, si tu le passes simplement en référence alors qu'il est crée dans un scope bien précis, ça va pas marcher non?
Je m'explique très mal
C'est vrai que après pour des choses très simples, un seul appel dans une fonction c'est peut être mieux de ne pas le faire avec des pointeurs.
En y repensant j'ai peut être pris une mauvaise habitude en effet, mais dites moi, vous utilisez le new sur une classe dans quels cas vous? Vous me faites douter...
« Disons simplement que je suis habitué a programmer dans des SDK ou tu as par exemple pour faire simple une grand fonction Init() et une fonction Destroy(), dans ce cas la tu vois peut être ou je veux en venir? »
parce que des gens mettent des pointeurs là où on pourrait parfois s'en passer, il faut faire pareil ? ![]()
(comprendre par là que moi je ne vois pas du tout où tu veux en venir)
« pour moi faire un new c'est l'assurance que l'object existe »
il existe aussi si tu ne fais pas de new hein. Mieux, il n'existe que localement si tu ne fais pas de new, et la plupart du temps tu ne t'en sers vraiment que localement de toute façon. ![]()
Moi non plus je ne vois pas où tu veux en venir....
Où est-ce que j'utilise un pointeur en C++.... Bonne question, quand j'ai à l'utiliser tout simplement, mais ce n'est pas une bonne habitude de créer des pointeurs en C++... C'est une des raisons pour lesquelles on a créé les références d'ailleurs !
Je peux les utiliser par exemple pour faker des interfaces en C++ puisque ce genre d'objet n'existe pas dans ce langage.
Je n'ai rien compris à ton exemple avec init() et destroy() malheureusement. Peut-être que ça rejoint les fake interfaces que j'ai décrit juste au dessus.
Bon ça y est, je suis tout embrouillé maintenant. En même temps je suis loin d'être un expert vu que je viens de recommencer le C++ après un plusieurs années.
Si tu fais un new dans un scope et que tu sors tu scope comment tu récupères ton objet si ton pointeur à été fait dans le scope? De là je pourrais ptet voir pourquoi au boulot on fait tout le temps comme ça. Sinon ya pas de difference avec un static?
Foudre
Posté le 24 février 2012 à 17:43:54
En y repensant j'ai peut être pris une mauvaise habitude en effet, mais dites moi, vous utilisez le new sur une classe dans quels cas vous? Vous me faites douter...
Seulement quand je n'ai pas le choix.
Typiquement ça va être lorsque je dois créer un objet dont le scope doit dépasser la fonction ou le bloc courant.
Par exemple imagines que tu crées un objet "bouton" dans une fonction et que tu le fournis à un objet "fenêtre" qui a une longue durée de vie. Si tu le déclares dans la pile et que la fenêtre existe toujours lorsque ta fonction retourne, c'est le crash assuré car celle-ci se trimballe une référence vers un objet détruit.
Donc voilà, mais il faut se dire ça oblige à savoir qui est propriétaire de l'objet et qui, ainsi, est responsable de sa destruction.
Si ton objet a besoin d'une durée de vie supérieure au bloc ou à la fonction dans laquelle il est créé, il te faudra l'allouer sur le tas, donc le plus souvent au moyen d'un new.
L'autre situation possible que j'entrevois, c'est éventuellement si l'objet est trop gros pour rentrer dans la pile mais j'ai jamais testé.
Utiliser des new pour du scope local c'est probablement mauvais en perfs et en plus c'est particulièrement casse-gueule si tu gères des exceptions et que tu n'utilises pas des smart pointers.