Bonjour,
quelle est la différence entre ces deux déclarations?
quelqu'un a une idée?Code:
1
2 nombre operator=(std::string nombre_str);//peut prendre un littéral nombre& operator=(std::string nombre_str);//peut prendre un littéral
Version imprimable
Bonjour,
quelle est la différence entre ces deux déclarations?
quelqu'un a une idée?Code:
1
2 nombre operator=(std::string nombre_str);//peut prendre un littéral nombre& operator=(std::string nombre_str);//peut prendre un littéral
à quoi sert le '&' dans le type de retour de fonction?
C'est we, les gens ne sont peut-être pas à la plage, mais ils peuvent être ailleurs…
Peut-être un début de réponse sur Stackoverflow ?
En gros, il s'agit de référence pour laquelle le C++ refuse que ce soit nul.
Mais ce n'est pas moi ze spécialiste.
Bonjour,
Le & pour un retour de fonction a la même signification qu'en déclaration de paramètre, qu'en déclaration de variable, qu'en qualificateur de this dans une déclaration de fonction! C'est un un peu à la base du C++, il indique une référence.
Plus de détails ici.
Ce qui distingue les 2 fonctions:
- la première retourne un objet nombre, ce qui n'a pas vraiment de sens ici car l'opérateur de génère pas de nombre!
- la seconde retourne une référence à un nombre, le code de l'opérateur terminant vraisemblablement par return *this;.
@dalfab confirme que cela ne sert à rien :mrgreen: : je me posais la question.
Il faut vérifier mais pour les opérateurs, retourner 1 référence permet de chaîner les opérateurs.
Par exemple, si tu fais std::string& operator*(std::string&), après tu pourras faire str4 = str3 * str2 * str1. str2 * str1 va donc produire 1 std::string temporaire qui pourra être utilisé pour faire str3 * tmp.
D'ailleurs, avec les opérateurs, tu ne peux pas vraiment faire ce que tu veux en terme de paramètres ou de retour : tu es presque obligé pour certains de mettre des références (il faut lire les références pour cela)
Pareil pour les opérateurs amis (friend) : cela permet de mettre l'objet pas forcément à gauche mais aussi à droite.
Par exemple, si tu fais std::string& friend operator+(int)], après tu pourras faire str1 = str2 + 4 ou str1 = 4 + str2.
Il faut vérifier, surtout avec les différentes normes qui ont peut-être modifié les comportements du C++03 :wow:
Cela aurait plus de sens de présenter str3 += str2 += str1; qui est horrible mais dont l'opérateur += retourne habituellement une référence. Ou simplement str3 = str2 = str1 puisqu'ici on parle de =. cppreference contient une page qui liste les prototypes usuels: https://en.cppreference.com/w/cpp/la...ions#Operators (il faut cliquer sur les titres du tableau).
Les prototypes sont mappés sur ce qu'on trouve en C avec les types de base. En pratique, je pense que retourner void cause moins de problème (sauf lorsqu'on implémente operator bool pour faire if ((x = foo())) ...).
Non, il n'y a aucune restriction sur le type, on peut mettre n'importe quoi. Il n'y a que operator++(int)/operator--(int) qui demande obligatoirement un int et operator-> qui devient inutilisable si on met n'importe quoi en retour (mais le compilateur n'empêchera pas de le faire). La seule réelle restriction étant le nombre de paramètre.
Un opérateur friend n'est pas nécessaire si on n'accède pas aux membres privées, une fonction libre fait l'affaire. Après, il y a un effet assez peu connut de friend qui fait que si le compilateur ne trouve aucun opérateur correspondant ne va pas lister les opérateurs amis si aucun des types en paramètre ne correspond:
Code:
1
2
3
4
5
6
7
8
9
10
11 struct A { friend A operator+(const A&, const A&) { return {}; } }; inline A operator-(const A&, const A&) { return {}; } class B {}; int main() { B() + 1; // operator+ non listé B() - 1; // operator- listé }
Code:
1
2
3
4
5
6
7
8
9
10 test.cpp:9:7: error: invalid operands to binary expression ('B' and 'int') 9 | B() + 1; // operator+ non listé | ~~~ ^ ~ test.cpp:10:7: error: invalid operands to binary expression ('B' and 'int') 10 | B() - 1; // operator- listé | ~~~ ^ ~ test.cpp:4:10: note: candidate function not viable: no known conversion from 'B' to 'const A' for 1st argument 4 | inline A operator-(const A&, const A&) { return {}; } | ^ ~~~~~~~~ 2 errors generated.
Merci pour ces précisions
j'ai essayé d'enchaîner les additions et les affectations sans le & et ça marche aussi. (?)
Oui ça marche, tu retournes une copie, copie utilisée pour être assignée au suivant.
Copie qui doit aussi être construite, puis détruite.
mais alors à quoi sert le & dans le type de retour?
je ne peux donc pas ici, comme n est un objet local?
comment utiliser ici un retour qui n'est pas une variable locale?
Code:
1
2
3
4
5
6
7 nombre nombre::operator-()const{ nombre n; n.positif= ! positif; n.partie_entiere=partie_entiere; n.partie_decimale=partie_decimale; return n; }
operator- c'est pas operator= :weird:
https://en.wikipedia.org/wiki/Operat..._C_and_C%2B%2B
si j'ai bien compris ce tableau, la référence de sortie ne se fait que avec = += -= /= *= ...
les opérateurs ou les méthodes qui modifient l'objet courant et qui renvoient *this?
Ton code est correct. L'opérateur- doit fabriquer une valeur, et donc c'est bien une valeur qu'il faut retourner, surtout pas une référence.
On ne retourne une référence que pour les fonctions et opérateurs qui doivent désigner une instance qui existait avant l'appel. Exemple des opérateurs dont le retour est une désignation (d'où référence):
Pour les trois premiers, on pourrait mettre void en retour, cela bloquerait des expressions complexes telles que a = b = c; ou ++ ++a;.
- l'opérateur d'assignation=, retourne une référence à *this.
- les opérateurs d'assignation avec opération@=, retournent une référence à *this.
- les opérateurs pré++ et pré--, retournent une référence à *this.
- l'opérateur[], retourne une référence à l'élément auquel on désire accéder.
- l'opérateur de déréférencement*, retourne une référence à l'élément auquel on désire accéder.
- l'opérateur d'accès par pointeur membre->*, retourne une référence à l'élément auquel on désire accéder.
Pour les trois derniers, la référence est plus vitale, on doit avoir en retour une référence. Par exemple pour t[i] = c;, le t[i] ne peut pas être une instance fabriquée, ça doit donner un moyen d'accéder à une partie de l'instance t.
Pour les trois derniers, ils peuvent aussi s'appliquer à un objet constant, ça peut alors retourner une instance. Comme modifier n'est pas possible, le retour est une référence constante (on désigne l'original intouchable) ou une instance fabriquée (une copie de l'original).
merci pour ces précisions