[C++] difficultés de programmation & héritage

Résolu/Fermé
helpme76 - 29 déc. 2006 à 23:57
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 - 5 janv. 2007 à 01:01
Bonjour,

je nage en plein desespoir, je dois rédiger un programme d'info en C++ et j'ai beaucoup de lacunes ! C'est pourquoi ma question n'est pas très bien ciblée d'ailleurs...
Alors, pour commencer, on me demande de créer un fichier avec une classe mère et plusieurs classes filles. (là, ca va.)

La classe mère contient pour information une chaine de caractères qui définit une opération précise, et par conséquent la classe fille à utiliser. (comment je fais pour désigner quelle classe fille utiliser à partir d'une chaine de caractère donnée dans la classe mère ?)

La classe mère contient une fonction membre commune, mais qui n'est pas la même selon la classe fille désignée . Comment dois je faire pour qu'une fonction commune change pour chaque classe fille ?

Alors voilà, je sais pas si ma question est très claire :s

Et sinon, je me demandais, est il possible de prendre une classe comme argument de fonction ?

A l'avance, merci beaucoup...

12 réponses

mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 7 812
4 janv. 2007 à 21:20
Bon pour la première question il faut bien faire la distinction entre la variable ou tu stocke la saisie de l'utilisateur et celle de l'objet lui-même. En général on met en protected les attributs de classe qui sont initialisées définitivement par le constructeur. Les autres peuvent être mises en public mais c'est mieux de les mettre en protected avec des accesseurs. Exemple :
#include <iostream>

class plop{
  protected:
  int x;
  int y;
  public:

  plop(const int & x0=0,const int & y0=0):x(x0),y(y0){}

  // lecture seule
  inline const int & get_x() const {
    return x;
  }

  // lecture seule
  inline const int & get_y() const {
    return x;
  }

  // si tu au
  inline void set_x(const int & x0){
    x=x0;
  }

  inline void set_y(const int & y0){
    y=y0;
  }
};

int main(){
  std::cout << "x0 ?" << std::endl;
  std::cin >> x0;
  std::cout << "y0 ?" << std::endl;
  std::cin >> y0;
  plop p(6,9);
  p.set_x(x0);
  p.set_y(y0);
  std::cout << "p.x=" << p.get_x() << std::endl;
  std::cout << "p.y=" << p.get_y() << std::endl;
  return 0;
}

Pour les toc utilises des std::string et l'opérateur == ce sera beaucoup plus simple.

Bonne chance
2
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 7 812
1 janv. 2007 à 23:55
C'est assez bizarre comme manière de faire, normalement on fait plutôt des liens dynamiques avec du virtual et tout le bastringue si on a une instance de la classe mère pour retomber sur la bonne classe fille.

Quoi qu'il en soit si tu peux déterminer la classe à partir d'une valeur stockée dans un chaine tu peux t'en sortir avec un dynamic_cast ou un static_cast.
#include <iostream>
#include <string>
#include <cassert>

class a_t{
  protected:
  std::string machaine;

  public:
  a_t(const std::string & machaine0="b1"):
    machaine(machaine0)
  {
    assert(machaine=="b1" || machaine=="b2");
  }

  inline const std::string & get_machaine() const{
    return machaine;
  }
};

class b1_t : public class a_t{
  public:
  b1_t(){}

  inline void f() const {
    std::cout << "b1" << std::endl;
  }
};

class b2_t : public class a_t{
  public:
  b2_t(){}

  inline void f() const {
    std::cout << "b2" << std::endl;
  }
};

void mafonction(a_t & x){
  if(x.get_machaine() == "b1"){
    const b1_t & x_cast = std::static_cast<b1_t>(x);
    x_cast.f();
  }else if(x.get_machaine() == "b1"){
    const b2_t & x_cast = std::static_cast<b2_t>(x);
    x_cast.f();
  }
}

Bone j'ai pas testé mais je pense que ça doit marcher, ou quelque chose dans ce goût là, je te laisser chercher...

Bonne chance
0
Merci !

Je vais essayer ca, je corrige mes diverses erreurs et je reviens si ca va pas :p
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
2 janv. 2007 à 17:25
salut.
Oui, il est tout à fait possible de mettre une class comme argument de fonction.
Par contre, je ne comprend pas du tout ça :
La classe mère contient pour information une chaine de caractères qui définit une opération précise, et par conséquent la classe fille à utiliser.
Pour l'autre partie, de fonction commune, mais différente, il suffit de déclarer la fonction virtual dans la class mère, et elle est redefinisable ensuite dans les class filles.
Globalement, tu es trop flou, et je ne comprend pas ce que tu cherche à faire.
0
désolé !
je vais essayer de m'expliquer mieux...
en gros la classe mère est une classe outil qui a comme information une chaine de caractère qui permet de définir une opération a effectuer.
chaque classe fille qui hérite correspond à une opération précise, et modifie, dans la fonction commune, un terme qui lui est propre.

(dans mon exemple, il y a, entre autres, les opérations alesage et percage, et donc les classes filles de outil seront outilaaleser et outilapercer)

voila, sinon, je crois que j'ai réussi à m'en sortir en ce qui concerne les questions auxquelles tu as déjà pu répondre...

merci déjà pour ca !
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
C'est à nouveau moi :(

alors, en attendant, j'avais effectivement essayé d'utiliser une fonction virtuelle ( bien que j'éprouve encore des difficultés à en comprendre l'impact...)
j'ai donc un peu galéré, mais voila, ca compile... pas tout à fait, puisqu'apparemment il m'indique des erreurs dans les fichiers.o, comment je peux les corriger, puisqu'il ne m'indique rien sur mes fichiers.cpp et .h ?

Apparemment le problème se poserait avec mes constructeurs et destructeurs (que j'ai choisis par défaut)
il dit que

[Linker error] undefined reference to 'foret::foret()'


et pareil avec le destructeur et pour toutes les classes (mère ou fille) que j'ai pu créer.
par exemple, (toutes mes classes sont à peu près pareilles)
j'ai
class foret : public outil //dérive de outil, devra modifier le diametre intérieur de la piece
      {
    public :
              foret();
             ~foret();
             void foret::usinage(piece p1, double epaisseur)
             {
             outil::usinage ( p1,  epaisseur);
             cout <<"la dimension qui sera modifiee est le diametre interieur \n";
             modif = p1.dint;
             }
    };



voila.
qu'est ce que je dois faire pour corriger ca ?

sinon, pour le code que tu m'as donné, j'ai essayé de le faire marcher, mais je ne connais pas certaines écritures que tu utilises, comme ce que signifie le & quand tu écris
void mafonction(a_t & x)
ou ce que signifie
const b1_t & x_cast
et quand je compile, il dit

expected unqualified-id before "static_cast"

qu'est ce qu'un "unqualified-id" ?


j'ai vraiment beaucoup de mal...
0
j'ai réussi a faire disparaitre les

[Linker error] undefined reference to...

finalement...

ceci dit, je n'ai toujours pas compris les codes que j'ai mentionnés ci dessous :)

je progresse je crois ! Merci !
0
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 7 812
3 janv. 2007 à 01:39
Tu définis un constructeur mais tu n'as pas donné le corps de la fonction :
class foret{
  protected:
  unsigned int nb_arbre;
  public:
  foret(unsigned int nb_arbre0):nb_arbre(nb_arbre0){}
  ~foret(){}
  //...
};

- Une fonction virtuelle c'est une fonction que l'on peut redéfinir dans une classe fille.
http://ltiwww.epfl.ch/Cxx/c2_7.html

- Attention à bien écrire std::cout et non cout, car a priori ta classe est définie dans un .hpp et il ne faut donc pas faire de "using namespace std;".

Bonne chance
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
3 janv. 2007 à 09:44
dans : type fonction(type & variable) le & signifie un passage par référence.
si tu ne met pas le &, dans la fonction, tu cré une nouvelle variable qui prend pour valeur ce qui est passer en argument à l'appel de la fonction.
En revanche avec le &, tu passe le pointeur : la variable dans la fonction et celle passer en paramètres auront la même adresse, et donc aussi la même valeur. Deux conséquences à cette méthode :
- si la variable est modifié dans la fonction la variable passer en paramètre le sera aussi
- la variable dans la fonction n'étant pas une copie de celle passer en paramètre, mais juste une copie de l'adresse, du temps processeur est gagné sur les objets volumineux (class très lourdes contenant beaucoup de membres)
const b1_t & x_cast ... Connai pas non plus.

par contre ce que tu veux faire est toujours aussi flou pour moi
0
Merci beaucoup pour tous vos renseignements, je crois que maintenant mon programme fonctionne et que c'est bon.

"- Attention à bien écrire std::cout et non cout, car a priori ta classe est définie dans un .hpp et il ne faut donc pas faire de "using namespace std;". "

A quoi sait t'on qu'il faut utiliser un fichier.hpp a la place d'un fichier .h ? Car j'ai bel et bien rangé mes classes dans des fichiers.h et ca n'a pas l'air de déranger le compilateur... du coup, j'ai effectiment mis des using namespace std; en haut de mes fichiers...(oups ?)

Sinon, pour répondre à ce que je veux faire avec mon programme, c'est un sujet tout bête qu'on nous demande en projet d'info.
Donc il n'a en réalité aucune utilité à proprement parler, c'est juste pour que j'apprenne à me servir de certains outils dont on nous a parlé, avec entre autre l'héritage et ses propriétés.
Et sinon le sujet consiste à définir plusieurs outils en vue d'usiner une pièce et de suivre l'évolution de ses dimensions au fur et à mesure de chaque opération d'usinage.
0
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 7 812
4 janv. 2007 à 09:55
A quoi sait t'on qu'il faut utiliser un fichier.hpp a la place d'un fichier .h ?

En fait c'est une notation mais tu peux mettre .h si tu préfères. L'avantage de .hpp c'est qu'on voit que c'est un header C++ qui ne pourra pas etre inclu par un programme en C.

using namespace std;

Jamais de using namespace dans un .hpp car en fait l'intérêt du namespace std c'est d'éviter les confusions. Imagine que tu aies une paramètre d'une classe "operation_bancaire" avec un attribut "cout". Au moment de compiler tu auras une ambiguité entre operation_bancaire::cout et std::cout, car dans la classe operation_bancaire les deux sont appelables par "cout". Or si cette classe inclue un header avec le using namespace c'est vraiment balo.

D'autres questions ?

Bonne chance
0
Concernant mon programme, ca a l'air de marcher, donc je n'ai plus de questions, (je crois !) Merci !

Bon, après, y'a encore tout plein de choses en c++ autres que dans mon sujet de programmation qui me paraissent obscures malgré les cours disponibles sur internet...

Mais bon !

Vous m'avez déjà beaucoup aidé et merci beaucoup pour ca !
0
ah en fait, j'ai une autre question ! (désolé !)

dans mon main, je déclare l'objet de ma classe piece au tout début :
piece finie (lpf,dextpf,dintpf);
lpf,dextpf,dintpf sont des valeurs numériques déjà "préenregistrées", mais si elles ne conviennent pas à l'utilisateur, il doit pouvoir les modifier.
donc voilà, je lui fais entrer ses valeurs à lui pour lpf,dextpf,dintpf, mais après, si je réaffiche les valeurs de piece brute, ce sont les premières qu'il me sort...

Comment faire pour qu'il prennent en compte les modifications de lpf,dextpf,dintpfqui ont été faites ?

Merci...
0
et encore une autre...
j'ai crée un ptit bout de caractères pour pouvoir effectuer des tests à l'aide de strcmp,
char rep[]="toc";
selon l'utilisateur, le "toc" de rep va devenir (en utilisant cin>>) "oui" ou "non".

une fois que c'est fait, j'aurai voulu savoir s'il était possible de réinitialiser à rep[]="toc" ?

le compilateur n'a pas l'air d'apprécier puisqu'il dit expected primary-expression before ']' token .

Promis, avec celle qui est juste au dessus, ce sont mes deux dernières questions...
0
Merci beaucoup !

grâce à toi j'ai plus de problème (mais jusqu'à quand, lol !)

En tous cas, vraiment, merci de m'aider à éviter ce genre de confusions...
0
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 7 812
5 janv. 2007 à 01:01
Pas de problème ! Pour tes problèmes ultérieurs ouvre un nouveau post.

Bonne chance
0