Salut,
Comment je peux faire que dans le operator+= il programme envoie un message de error si
opérande est const ?
merci d'avance
Salut,
Comment je peux faire que dans le operator+= il programme envoie un message de error si
opérande est const ?
merci d'avance
Salut, et bienvenue sur le forum...
D'abord et avant tout, pourquoi voudrais tu le faire
Typiquement, les opérateurs mathématique suivi d'affectation ( +=, -=, *=, /= ) renvoient une... référence sur l'objet en cours (qui seul sera modifié), et le compilateur refusera l'invocation des opérateurs si l'objet en cours est constant...
En effet, si tu as une classe proche de
le code suivant sera accepté (parce que c1 est non constant)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 class MaClass { public: MaClass& operator+=(MaClass const & rhs) { /* le calcul "qui va bien" */ return *this; } };
Par contre, le code suivant sera refusé dés la compilation parce que l'objet en cours (c4) est constant et que tu ne peux invoquer que les fonctions déclarées constantes au départ d'objets constants
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 void foo() { MaClass c1; MaClass c2; c1+=c2; /* ceci fonctionne aussi car c3 ne sera pas modifié */ MaClass const c3; c1+=c3; }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 void bar() { MaClass const c4; MaClass c5; c4+=c5; }
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
Je veux just changer le error message pour que ca soit plus clair...
Comment je peux utiliser try/catch pour controler le operator>> (si le type de Elem n'ai pas bonne)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 template <typename Elem, size_t N> std::istream& operator>> (std::istream &input, Poly_S<Elem, N> &pol) { size_t deg, i; std::cout << "Degre du Poly (MAX :" << N << ") : "; std::cin >> deg; deg++; // Dimension = degre +1 if(deg> N+1) throw "Degre for Poly statique is too big"; else { // Initialisation des cases non utilisés par le Poly à 0 for(i=N; i>deg-1; i--) pol[i]=Elem(); for(i=deg-1;i>0;i--) { std::cout << "Coefficient d'ordre "<<i<<" ? "; std::cin >> pol[i]; } std::cout << "Coefficient d'ordre "<<i<<" ? "; std::cin >> pol[i]; return input; } }
Comme je te l'ai expliqué, si tu essaye de passer un objet constant comme paramètre d'une fonction qui attend un objet non constant, l'erreur se produit directement au moment de la compilation.
L'erreur que tu obtiens est alors propre au compilateur, et il est impossible de les modifier.
Lorsque tu lance une exception avec throw et que tu la récupère dans un bloc try... catch, il s'agit d'erreurs qui surviennent lors de l'exécution du code qui, fatalement, survient beaucoup plus tard que la compilation
De plus, tu nous parle dans ton premier message de l'opérateur += et dans le second de l'opérateur >> (que tu manipule d'ailleurs relativement mal, et qui ne me semble pas être des mieux adaptés à ce que ton code reflète )
Je te conseillerais donc volontiers de réfléchir un peu à la citation de ma signature et de remettre un peu d'ordre dans tes différentes idées.
Et, si je peux me permettre un dernier conseil, tu devrais réfléchir à déléguer correctement les différentes responsabilités: si une fonction a plus d'une responsabilité, c'est sans doute qu'elle en a trop
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
merci pour les conseil en fait j'ai un classe polynome qui est un template de Elem,est taille de polynome
et je veux recharger operator>>
Est-ce que c'est pas bonne mon érciture?
Est-ce que avec try/catch je peux récupérer les erreur dans ce style mouvais valeur pour taille ou Elem?
Bon, commençons par le commencement...
Normalement, l'opérateur >> est ce que l'on appelle un opérateur de flux.
Dans le cas de >>, le passage de l'information va du flux (le fichier, ou le clavier, par exemple) vers la donnée.
De plus, le premier paramètre de la fonction (parce qu'un opérateur n'est jamais qu'une fonction bien déguisée ) est... une référence vers le flux d'entrée à manipuler.
L'idée générale est, simplement, de se permettre d'écrire un code proche deDans le code que tu nous présente, il serait donc intéressant d'utiliser le flux passé en paramètre (nommé input) plutôt que carrément cin.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 Polynome p; std::cin >> p;
Seulement, cin n'est qu'un des type de flux qui existe d'origine: c'est le flux d'entrée standard, généralement associée au clavier.
Or, il existe d'autres flux d'entrées, tels que les fichiers (ifstream pour le flux d'entrée) ou les flux de conversion en chaines ((i)stringstream) qui sont également susceptibles de réagir avec la surcharge de l'opérateur >> prenant un istream comme premier paramètre.
Tu ne devrais normalement pas surcharger l'opérateur >> tel que tu le fais, mais tu devrais plutôt créer une fonction membre "classique" que tu nommerais, par exemple askValue (pour que le nom indique ce que tu fais), et qui prendrait la forme de
En effet, si, plus tard, toi (ou quelqu'un d'autre) regarde la déclaration de ta classe Polynome, il va voir que tu as redéfini l'opérateur >>.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 /* je passe la déclaration des template */ class Polynome { public: void askValue() { /* traitement complet comme*/ std::cout<<"blabla"; std::cin>> truc; std::cout<<"bidule"; std::cin>>machin; } };
Cette personne peut donc être tentée de l'utiliser avec... n'importe quel type de flux d'entrée, et pourrais donc essayer d'écrire un code proche de
qui, tu n'y a peut être pas pensé, aura un comportement pour le moins... surprenant étant donné que ton implémentation:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 std::ifstream ifs("fichier.txt"); Polynome p; ifs>>p;
- utilise explicitement le flux de sortie standard std::cout (ce qui est encore le moins grave)
- utilise explicitement le flux d'entrée standard std::cin (ce qui l'est beaucoup plus)
Ensuite, comme je te l'ai indiqué, il faut veiller à déléguer correctement les différentes responsabilités, et, tant qu'à faire, il faut utiliser au maximum l'idiome RAII (Ressource Acquisition Is Initialisation).
Le RAII consiste à tout faire pour que l'instance d'un objet soit utilisable (et correctement initialisée) dés le moment de la construction.
Et ca, ca devrait se faire... en prévoyant le constructeur adéquat.
L'idée est donc de séparer l'étape qui consiste à gérer l'introduction des différentes valeurs de l'étape qui consiste à créer ton polynome, sous une forme proche de
Enfin, il faut comprendre que ce qui est lancé par throw (et qui est géré dans la partie catch d'un bloc try catch) est... une exception.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 template <typename T> class Polynome { private: std::vector<T> elems_; public: /* par défaut, il n'y a aucun élément dans le polynome */ Polynome():elems_(){} /* mais nous pouvons créer un polynome avec un nombre * quelconque d'éléments existants */ explicit Polynome(std::vector<T> const & e):elems_(e){} /* ou en sachant quel est le degré maximal */ explicit Polynome(size_t deg):elems_(deg+1){} size_t size() const{return elems_.size();} /* permettons d'accéder aux éléments par leur index */ T const & operator[](size_t index) const { if(index>= elems_.size()) throw std::out_of_range(); return elems_[index]; } /* permettons de rajouter un élément à la fin */ void push_back(T const & toadd) { elems_.push_back(toadd); } /* et de supprimer l'ensemble des éléments */ void clear(){elems_.clear();} /* Mais rien ne nous empêche d'accepter de définir le polynome * au départ d'un flux (autre que std::cin */ friend istream& operator>>(istream & input, Polynome & p) { /* supprimons les coefficients existants... */ p.clear(); /* Il faut bien choisir un format pour le flux... * cet opérateur ci va considérer que le flux est représenté * au format CSV, tous les coefficients (y compris les nuls) * sur la même ligne et séparés par une virgule */ std::string temp; std::getline(input, temp) std::stringstream ss; ss<< temp; T value; char c; while((ss>value)) { p.push_back(value); ss>>c; } } }; template<typename T> Polynome<T> createPolynome() { /* le tableau de coefficients */ std::vector<T> coefs; cout<<"Quel est le degré du polynome ?"; size_t deg; cin>>deg; /* réservons d'un seul coup tout l'espace nécessaire */ coefs.reserve(deg+1); /* introduisons les coefficients dans l'ordre croissant */ for(size_t i=0;i<deg+1;++i) { int c; std::cout<< "Quel est le coefficient pour X^"<<i<<" ?"; std::cin >> c; coef.push_back(c); } /* créons le polynome et renvoyons le */ return Polynome(coefs); }
Il faut aussi comprendre qu'une exception est un événement
La tentative de définir N+1 valeurs alors qu'il n'en faut normalement que N n'entre, à mon sens, pas dans cette définition des exceptions.
- dont on espère qu'il n'arrivera pas (qu'il surviendra... exceptionnellement)
- qui place un objet de ton application dans un état invalide (ou qui risque de le faire)
- dont (une partie de la) la résolution doit être laissée à la fonction appelante (ou à une ou plusieurs des fonctions appelantes qui ont mené à cet événement).
Et ce, d'autant plus qu'il "suffit" d'adapter la logique pour qu'il n'y ait que N itérations d'introduction de valeurs, ainsi que je te l'ai montré plus haut
Par contre, il est cohérent de lancer une exception si l'on essaye d'accéder à un index supérieur à l'index maximal accessible car l'origine se trouve vraisemblablement... au moment où tu as déterminé l'index souhaité
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
En fait c'est un projet où je dois recharger l'opérateur >>,l'opérateur << ...
ca doit être flux parce qu'on entre les valeur de polynome en clavier.
J'ai un code come ca
Dans le cas où le Éléments de polynôme qu'on entre est Complexe et on entre un rationnel pas exemple ou char c'est pas un exception?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 Poly_S<double,5> polyS_double; cout<<"Entre le polynome statique avec element double"<<endl; cin >> polyS_double; cout << polyS_double<<endl;
ou pour la taille de polynôme au lieu de etntre un size_t on entre un char c'est pas un exception?
P.S. ce que je veux faire c'est dans le cas d'opérande erronée ?
Détection et traitement d'exception (try / catch).
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager