OVH Cloud OVH Cloud

[debutant] Premier programme en C++, qu'en pensez-vous?

54 réponses
Avatar
Beware
Bonjour,

J'ai depuis une grosse semaine commenc=E9 =E0 apprendre le C++. Je
l'apprends de mani=E8re autonome (ce qui n'est pas totalement une
excuse). Pour ce fait, je suis les tutos pour C++ du site du zero.

J'ai donc utilis=E9 leur exemple de (tr=E9s tr=E9s) petit RPG, mais qui me
permet de manipuler certains concept de base en C++.

Pour en revenir donc =E0 ce message, je voudrais demander aux
connaisseurs qui peuvent et surtout qui veulent si il pouvait jeter un
oeil =E0 mon code pour me dire tout ce qu'il ne va pas et que par
cons=E9quent je devrais am=E9liorer (ou carr=E9ment changer :) )

Merci =E0 eux.

L'ensemble des fichiers sont disponibles =E0 cette adresse :
http://beware007.free.fr/Projet_C++/rpg/

Au revoir

PS : Je pr=E9cise que j'ai cod=E9 sous C::B et sous Linux.

10 réponses

1 2 3 4 5
Avatar
era
Mathias Gaunard a écrit :
et
assez dangereux finalement, si tu veux mon avis.
Tu ferais mieux de virer tous ces pointeurs...



On sait tous que les armes sont dangereuses.
Ca peut partir tout seul !
Avatar
Mickaël Wolff
Beware wrote:


Pour le combat je verrais ca aprés (l'interet de faire un new et un
delete).



En fait il voulait juste dire qu'il fallait que tu utilises
l'allocation dynamique quand c'est nécessaire, et pas à tout bout de champ.

Cependant, si j'ai bien tout lu freud, il va me creer ce vector a
chaque fois que je ferais appel a la fonction equiperarme, n'est ce
pas la un peu lourd ?



Tu te rends bien compte que ce n'est pas le bon endroit, c'est déjà
bien ;) Tu peux le mettre dans le constructeur de ton armurerie dans un
premier temps.

Bien que je ne voie pas pour l'instant ou l'initialiser autre part et
y avoir accés dans mes fonctions.



Comme dit dans le constructeur, en ajoutant une donnée membre à ta
classe.

--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org

Seeking for a position <http://lupusmic.org/pro/>
Avatar
pjb
Beware writes:

Pour l'histoire de m_arme, j'ai compris ce que tu voulais dire. Il est
possible que je l'ai modifié entre temps sans prévenir.

Pour le combat je verrais ca aprés (l'interet de faire un new et un
delete).
Parce que la, j'avoue que je bloque un peu sur l'utilisation du
vector. j'ai d'ailleurs une question :

j'ai mis ce code :
vector < Arme > armes_en_stock;
armes_en_stock.push_back(Arme("Lance", LANCE_DG));
armes_en_stock.push_back(Arme("Epée en Bronze", EPEE_BRONZE_DG));
armes_en_stock.push_back(Arme("Hache en fer", HACHE_FER_DG));
armes_en_stock.push_back(Arme("Hallebarde", HALLEBARDE_DG));
armes_en_stock.push_back(Arme("Epée à doubles tranchants",
EPEE_DOUBLE_TRANCHANT_DG));
armes_en_stock.push_back(Arme("Hache Lourde", HACHE_LOURDE_DG));

dans la fonction equiperarme de mon armuerie.cpp.

Cependant, si j'ai bien tout lu freud, il va me creer ce vector a
chaque fois que je ferais appel a la fonction equiperarme, n'est ce
pas la un peu lourd ?

Bien que je ne voie pas pour l'instant ou l'initialiser autre part et
y avoir accés dans mes fonctions.



Donc tu es en train de dire que tu as un Armurier, qui a un
Stock d'Armes, et il y a des Armes, qui peuvent être en Stock ou non.

class Armurier {
private:
Stock<Arme> stock;
Bourse bourse;
public:
Armurier();
virtual ~Armurier();
virtual Or& acheter(Arme& a);
virtual Arme& vendre(Arme& a,Or& o);
// ...
};

template <class Chose> class Stock {
private:
std::vector<Chose> contenu;
public:
Stock();
virtual ~Stock();
virtual void ajouter(Chose& c);
virtual void enlever(Chose& c);
// ...
};


N'ajoute pas toi même des armes à un vecteur. Tu vois bien que ça ne
veut rien dire. On ne peut ajouter des Armes qu'à un Stock d'Arme, et
seul l'armurier peut faire ça:

Or& Armurier::acheter(Arme& a){
Or prix=0.50*Cotation::prix(a)
if(prix<bourse){
bourse.retrancher(prix);
stock.ajouter(a);
return(prix);
}else{
thow std::exception("Trop pauvre pour acheter cette arme");
}
}

Il faut bien sur que l'armurier démarre avec de l'or pour pouvoir
acheter son stock d'arme...

Armurier::Armurier(Or& capital)
:bourse(capital)
{
}



Mais de toutes façons, il y aura bien une phase d'initialization où tu
va devoir créer tous les objets dans la situation initiale. Le mieux
c'est de ne pas câbler en dur cette situation initiale, mais de suivre
un "script", un fichier qui indiquera combien d'armurier il faut
créer, combien de forgerons (pour fabriquer les armes), comment ils
s'appellent, et quelles armes ils veulent mettre en stock, etc.

--
__Pascal Bourguignon__
Avatar
Beware
Bonjour,

J'ai donc suivi vos conseils (enfin au mieux j'espère) :

- j'ai enlevé le new (et le delete) pour combat1 dans le main,
désormais j'utilise une référence pour passer l'objet combat1 aux
fonctions qui en ont besoin

- j'ai remplacé certains #define par des enums. Je l'ai pas fait pour
tous, notamment pour les #defines ou il n'y a que deux valeurs
possible.

- j'avais rajouté une classe bouclier en plus de celle arme (basé sur
le même principe) qui modifie les dégâts subit.

- j'ai donc utilisé les vector pour stocker les armes et les
boucliers. Ce qui est vrai simplifie l'écriture (moins de ligne à
écrire). J'ai donc ajouter deux nouvelles entrées dans ma classe
armurerie, et mis les entrées (push_back) dans le constructeur (pour
l'instant en tout cas).

Le seul problème lié a ce changement est qu'il faut désormais que je
crée l'objet armurerie alors qu'auparavant les fonctions était en
static et je les appelais directement dans mon combat. Mais je ne
saurais dire si cela peut poser problème, si cela surcharge
inutilement le programme exécuté.

Merci à tous pour vos conseils.

Les changements à venir sont (pour l'instant) :

- changer le comportement du bouclier :
- pas de bouclier avec les armes lourdes (hache lourde +
hallebarde + épée double tranchants)

- il faut que je trouve un changement sur l'attaque ou la défense
suivant l'arme choisit.

Au revoir.
Avatar
Stan
On 28 juil, 19:08, Gabriel Dos Reis wrote:

Et écrire beaucoup de programmes.  C'est un peu comme apprendre à
conduire, il ne suffit pas de lire le code de la route ; il faut aussi
de la pratique.  Beaucoup de pratique.

Cultiver du goût pour l'élégance et la simplicité.




Deux qualités que l'on trouve souvent dans les ouvrages
de références, mais qui, je ne sais pour quelle raison,
disparaissent des programmes.

A croire que beaucoup de programmeurs fuient la simplicité.

--
-Stan
Avatar
Michael DOUBEZ
Beware a écrit :
[snip]
- j'ai donc utilisé les vector pour stocker les armes et les
boucliers. Ce qui est vrai simplifie l'écriture (moins de ligne à
écrire). J'ai donc ajouter deux nouvelles entrées dans ma classe
armurerie, et mis les entrées (push_back) dans le constructeur (pour
l'instant en tout cas).

Le seul problème lié a ce changement est qu'il faut désormais que je
crée l'objet armurerie alors qu'auparavant les fonctions était en
static et je les appelais directement dans mon combat. Mais je ne
saurais dire si cela peut poser problème, si cela surcharge
inutilement le programme exécuté.



C'est pas une obligation si tu ne le veux pas: tu peux utiliser une
globale que tu initialise au début du jeux (c'est l'approche
procédurale). Ou alors, tu peux utiliser une fonction qui te renvoie une
variable static (cet idiome est utile en C++) initialisée au premier appel:

vector<Arme>& Armurerie::contenu()
{
static vector<Arme> armes;
if(armes.empty())
{ // initialise les armes
// soit les push_back ou appel à une fonction
// qui rempli ton vector<Arme>
}

return armes;
}

Ici armes n'est initialisé qu'une seule fois: la première fois que tu
appelles contenu() car armes est vide la première fois mais pas aux
appels suivants. Tu utilises contenu() comme un vector habituel:

const size_t nb_arme=Armurerie::contenu().size();
for(size_t i=0;i<nb_arme;++i)
{
Arme& arme=Armurerie::contenu()[i];
//...
}

C'est juste un peu plus laid.

--
Michael
Avatar
James Kanze
On Jul 28, 7:08 pm, Gabriel Dos Reis wrote:
Antoine writes:



[...]



> La seule manière valable pour apprendre depuis la création
> des langages est avec les livres de référence.



Et écrire des programmes -- prend n'importe quel problème (de
taille raisonnable) qui a une solution algorithmique ; essaie
de programmer la solution.



Il ne suffit pas de les écrire. Il faut les faire marcher, et de
les faire lire par des autres (pour s'assurer que d'autres
peuvent les lire).

--
James Kanze (GABI Software) email:
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
Jean-Marc Bourguet
Michael Doubez writes:

On 29 juil, 21:39, Stan wrote:
On 28 juil, 19:08, Gabriel Dos Reis wrote:

> Et écrire beaucoup de programmes.  C'est un peu comme apprendre à
> conduire, il ne suffit pas de lire le code de la route ; il faut aussi
> de la pratique.  Beaucoup de pratique.

> Cultiver du goût pour l'élégance et la simplicité.

Deux qualités que l'on trouve souvent dans les ouvrages
de références, mais qui, je ne sais pour quelle raison,
disparaissent des programmes.



D'une part, les livres ne s'attaquent quà des cas simples ou


[...]
D'autre part, au moment de l'écriture, un programmeur est dans une


[...]

Tu oublies évidemment que le mot clé est "disparaissent", et que c'est ce
qui se passe en pratique. La conception initiale est souvent élégante et
simple. Simplement ce sont des qualités qui ont tendance à ne par
survivre facilement aux évolutions. Elles disparaissent parfois avant la
première version -- des changements, des compléments interviennent trop
tard et vont dans une direction non anticipée -- et très souvent par après.

A noter -- et je suis loin d'être le premier à faire cette remarque -- que
la reconception ab nihilo est rarement une bonne chose, en particulier tant
qu'on ne maîtrise pas le pourquoi des complications existantes. Celles-ci
sont la mémoire d'une série d'aspects qui n'ont été découverts que trop
tard lors de la conception précédente, si on les ignore, on les
redécouvrira tout aussi tard avec le même effet. Sans parler de la
pression qu'il y aura a rester "bug compatible" avec la version précédente.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Avatar
Michael Doubez
On 29 juil, 21:39, Stan wrote:
On 28 juil, 19:08, Gabriel Dos Reis wrote:

> Et écrire beaucoup de programmes.  C'est un peu comme apprendre à
> conduire, il ne suffit pas de lire le code de la route ; il faut aussi
> de la pratique.  Beaucoup de pratique.

> Cultiver du goût pour l'élégance et la simplicité.

Deux qualités que l'on trouve souvent dans les ouvrages
de références, mais qui, je ne sais pour quelle raison,
disparaissent des programmes.



D'une part, les livres ne s'attaquent quà des cas simples ou
caractéristiques d'un problème. Or, il en va autrement d'un logicel
avec plusieurs intervenants, une histoire et toute une base de donnée
de change request qui ont sûrement fait débordé le domaine
initialialement abordé.

D'autre part, au moment de l'écriture, un programmeur est dans une
ligne de reflexion/pensée et ce qu'il écrit lui parait juste et
logique. Ce n'est qu'en revenant dessus que la complexité apparait. Il
faut donc prendre du recul par rapport au code produit. Dans un livre
le code est l'expression d'une idée ou une illustration, les rapports
sont inversés.

A croire que beaucoup de programmeurs fuient la simplicité.



Le simplicité est diffcile, demandes beaucoup de puissance
intellectuelle et un fin ressenti (appelé très justement "goût" par
Gabriel Dos Reis) de la justesse d'un état.
Les japonnais, maîttres en simplicité, mettent des années à parveni r à
un résultat satisfaisant est c'est leur culture. Alors c'est pas
étonnant que ce soir difficile pour d'autres.

--
Michael
Avatar
Beware
Bonjour,

j'ai (encore) une question :

Faut il implementer dans chacune des classes que l'on code et ce
évidement si l'on ne s'en sert pas :
- le desctructeur,
- le constructeur par copie,
- l'opérateur d'assignation ?

Merci
1 2 3 4 5