Flux rss
Collection CommentCaMarche.net
Rechercher : dans
Par : Mots clés Nom d'utilisateur
Messages sans réponse

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

helpme76, le vendredi 29 décembre 2006 à 23:57:06 
 Signaler ce message aux modérateurs

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...

Configuration: Windows XP
Firefox 2.0.0.1

1

mamiemando, le lundi 1 janvier 2007 à 23:55:32
  • +1

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

Répondre à mamiemando

2

helpme76, le mardi 2 janvier 2007 à 15:55:12

Merci !

Je vais essayer ca, je corrige mes diverses erreurs et je reviens si ca va pas :p

Répondre à helpme76

3

Char Snipeur, le mardi 2 janvier 2007 à 17:25:03
  • +1

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. Salutation !
Char Snipeur

Répondre à Char Snipeur

5

helpme76, le mardi 2 janvier 2007 à 20:08:01

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 !

Répondre à helpme76

4

helpme76, le mardi 2 janvier 2007 à 17:56:24

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...

Répondre à helpme76

6

helpme76, le mardi 2 janvier 2007 à 20:45:42

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 !

Répondre à helpme76

7

mamiemando, le mercredi 3 janvier 2007 à 01:39:14
  • +1

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

Répondre à mamiemando

8

Char Snipeur, le mercredi 3 janvier 2007 à 09:44:34
  • +1

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 Salutation !
Char Snipeur

Répondre à Char Snipeur

9

helpme76, le jeudi 4 janvier 2007 à 00:33:07

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.

Répondre à helpme76

10

mamiemando, le jeudi 4 janvier 2007 à 09:55:18
  • +1

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

Répondre à mamiemando

11

helpme76, le jeudi 4 janvier 2007 à 13:07:13

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 !

Répondre à helpme76

12

helpme76, le jeudi 4 janvier 2007 à 18:12:17

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...

Répondre à helpme76

13

helpme76, le jeudi 4 janvier 2007 à 20:36:11

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...

Répondre à helpme76

14

mamiemando, le jeudi 4 janvier 2007 à 21:20:16
  • +2

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

Répondre à mamiemando

15

helpme76, le jeudi 4 janvier 2007 à 22:48:48

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...

Répondre à helpme76

16

 mamiemando, le vendredi 5 janvier 2007 à 01:01:50
  • +1

Pas de problème ! Pour tes problèmes ultérieurs ouvre un nouveau post.

Bonne chance

Répondre à mamiemando
Modifier le dossier d'installation par défaut C:\Program Files Par défaut, l'installation de la plupart des programmes et logiciels se fait dans le dossier C:\Program Files. Pour une raison ou une autre, vous voulez changer ce dossier par un autre (sur une autre partition en cas de problème d'espace disque par... www.commentcamarche.net/faq/sujet-11458-modifier-le-dossier-d-installation-par-defaut-c-program-files
C:\PROGRA~1\MYWEBS~1\BAR\1 bin\M3playing.DLL Bonjour,l'ecran affiche :erreur de chargement de :C:\PROGRA~1\MYWEBS~1\BAR\1 bin\M3playing.DLL cela veut dire et que dois je faire pour le corriger? MERCI d'avance!! www.commentcamarche.net/forum/affich-8510724-c-progra-1-mywebs-1-bar-1-bin-m3playing-dll
[ langage C] programmer un jeux tres dificile Bonjour, Tout d’abord je me présente je m’appelle radwen, et je suis un étudiant en informatique appliquer a la gestion. Et je suis en première année. Mon problème et : J’ai un projet qui consiste à programmer un jeu qui s’appelle MasterMind en C.... www.commentcamarche.net/forum/affich-2462693-langage-c-programmer-un-jeux-tres-dificile
C:\Program files\Avira\Antivir Personal editi (Résolu)Bonjour,depuis ce matin j'ai un message qui s'affiche tout le temps . VOICI CE QU'IL Y A D'ECRIT : The application module . C:\Program Files\Avira\AntiVir Personnal Edition Classic\rcimage.dll Cannot be found or has been modified or destroyed . The... www.commentcamarche.net/forum/affich-9513602-c-program-files-avira-antivir-personal-editi
C:\PROGRA~1\MYWEBS~1\BAR\1 bin\M3playing.DLLBonjour, svp chaque que j'allume mon pc une fenetre s'affiche ma'affiremant que il y a erreur de chargement C:\PROGRA~1\MYWEBS~1\BAR\1 bin\M3playing.DLL j'ai essayé de telechargé le Dll specifié sur +ieurs sites mais sans aucun resultat (). 1)svp à... www.commentcamarche.net/forum/affich-8696324-c-progra-1-mywebs-1-bar-1-bin-m3playing-dll
Program files fichier inexistantBonjour, j'ai un message d'erreur lorsque je lance Directeur HP : le fichier C :\programFiles\HP\Digital Imaging\skins\oov1\skin.xml. n'existe pas J'ai une HP psc2410 photosmart tou-en-un. Cette erreur est survenue après avoir installé néro 7 . Depuis... www.commentcamarche.net/forum/affich-3890960-program-files-fichier-inexistant
Programmation réseau - Les socketsIntroduction aux sockets La notion de sockets a été introduite dans les distributions de Berkeley (un fameux système de type UNIX, dont beaucoup de distributions actuelles utilisent des morceaux de code), c'est la raison pour laquelle on parle... www.commentcamarche.net/contents/sockets/sockintro.php3
Introduction au langage CPetite histoire du C Le langage C a été mis au point par D.Ritchie et B.W.Kernighan au début des années 70. Leur but était de permettre de développer un langage qui permettrait d'obtenir un système d'exploitation de type UNIX portable. D.Ritchie... www.commentcamarche.net/contents/c/cintro.php3
Langage C - Les chaînes de caractèresQu'est-ce qu'une chaîne de caractères ? Une chaîne de caractères (appelée string en anglais) est une suite de caractères, c'est-à-dire un ensemble de symboles faisant partie du jeu de caractères, défini par le code ASCII. En langage C, une chaîne... www.commentcamarche.net/contents/c/cstring.php3