Je sais que je peux facilement répondre à cette question pour moi par génératine le code et voir s'il compilait. Mais puisque je ne pouvais pas trouver une question similaire, je pensais que c'était la connaissance de la peine d'être partagé.
Dis que je surcharge de l'opérateur + de MyClass. Puis-je surcharger plusieurs fois. Surcharge différente pour différents types. Comme ceci: La raison pour laquelle je veux faire est que je construis une classe que je veux être aussi optimisée que possible. La performance est la plus grande préoccupation pour moi ici. SO CASTING ET À L'UTILISATION DE CAS DE COMMUTURE À L'INTÉRIEUR DE L'OPÉRATEUR + La fonction surchargée n'est pas une option. Je vous remarquerez, j'ai fait les deux surcharges en ligne. Supposons une seconde que le compilateur affirme effectivement mes surcharges, puis il est prédéterminé lors de la compilation de l'heure de compilation, et je sauvegarde l'appel à une fonction (par inlinge) + un scénario de cas de commutation complexe (en réalité, il y aura 5+ surcharges pour + opérateur), mais je suis toujours capable d'écrire facilement du code en utilisant des opérateurs arithmétiques de base.
Donc, vais-je obtenir le comportement souhaité? P> p>
3 Réponses :
oui. p>
Ces fonctions de l'opérateur ne sont que des fonctions ordinaires avec les noms spéciaux opérateur @ code>. Il n'y a aucune restriction qu'ils ne peuvent pas être surchargés. En fait, l'opérateur
<<< / code> utilisé par iostream est un opérateur avec plusieurs surcharges. P>
Je me sens mal d'encombrer votre réponse avec un commentaire. Tache sur.
Oui, vous pouvez surcharger des opérateurs comme celui-ci. Mais je ne suis pas sûr de ce que "cas de commutation" vous parlez de. Vous pouvez vivre avec une surcharge si vous avez un constructeur de conversion Notez que vous devriez surcharger ces opérateurs par des fonctions non membres. Dans votre code 5 + C1 CODE> ne fonctionnerait pas, car il n'y a pas d'opérateur qui prend une INT de côté gauche. Ce qui suit fonctionnerait p>
inline const MyClass operator+(const MyClass &lhs, const MyClass &rhs) {
// ...
}
Johannes, ce constructeur de conversion implicite pourrait ne pas être une bonne idée. Pour une, les conversions implicites IME se révèlent généralement être une mauvaise idée tôt ou tard de toute façon, mais aussi parce qu'ElaDidan veut faire cela parce que "je construisais une classe que je veux être aussi optimisée que possible." Dans ce cas, les surcharges sont meilleures de toute façon.
Oh, et de copier de manière générale inline bla myClass :: code> dans
myClass code> ne semble pas du tout comme vous.
:) code>
La forme canonique d'implémentation Quelque chose comme ça devrait faire: P> opérateur + () code> est une fonction libre basée sur
opérateur + = () code>, que vos utilisateurs s'attendont quand vous aurez
+ code>.
+ = code> modifie son argument de gauche et devrait donc être membre. Le
+ code> traite ses arguments symétriquement et devrait donc être une fonction libre.
//Beware, brain-compiled code ahead!
class MyClass {
public:
MyClass& operator+=(const MyClass &rhs) const
{
// code for adding MyClass to MyClass
return *this;
}
MyClass& operator+=(int rhs) const
{
// code for adding int to MyClass
return *this;
}
};
inline MyClass operator+(MyClass lhs, const MyClass& rhs) {
lhs += rhs;
return lhs;
}
inline MyClass operator+(MyClass lhs, int rhs) {
lhs += rhs;
return lhs;
}
// maybe you need this one, too
inline MyClass operator+(int lhs, const MyClass& rhs) {
return rhs + lhs; // addition should be commutative
}
+1 pour la bonne forme. Cependant, je voudrais probablement utiliser Boost.Pérateurs pour générer gratuitement les fonctions gratuites :)
TRÈS BASIC QN: Votre définition pour + nécessite que LHS soit un const, tandis que le code nécessite que vous écris LHS + = rhs. Il semble que vous ayez besoin de changer votre code ou votre définition. Ai-je raison?
@Anon: C'était un majeur de la mienne.
Je pense que l'opérateur + devrait faire: myclass temp = lhs; temp + = rhs; Retour TEMP; code>. Sinon, si je fais:
myClass A = B + C; code>, puis
B code> changements.
@ Bill.not donc. LHS est reçu BYVAL. Depuis que nous retournons cette copie superficielle, nous ne modifions pas le paramètre d'origine et nous ne créons aucune instance inutile de myClass. Votre solution n'est valable que si nous recevons LHS BYREF (MyClass & LHS) et si nous surchargons l'opérateur "=";
@eladidan: myClass Temp = LHS code> invoque le Copie Constructor i>, pas l'opérateur d'affectation, mais sinon vous avez raison.
Si vous êtes concerné par la performance, à partir d'un point de vue de la classe, retournez
* Ceci code> via
const myClass & code> sera meilleur. Maintenant, à partir d'un point de vue de l'utilisateur (sauf si vous ne compilez pas sur C ++ 0x), vous devez utiliser
+ = code> au lieu de
+ code> et
= code> = code> Pour éviter les temporaires inutiles qui ne seront peut-être pas optimisés par certains compilateurs de merde.
Je ne sais pas pourquoi c'était voté à la fois. C'est une question parfaitement valable. (Le fait que vous trouviez que cette information ailleurs n'a aucune raison de ne pas trouver la réponse ici aussi.)
@paercebal: il met en œuvre la somme d'une somme, pas d'incrément. S'il impliquait
opérateur + = code>, renvoyer une référence (après avoir modifié l'état interne), mais
A + B code> n'est pas destiné à modifier le
code>, mais produise plutôt une troisième valeur qui diffère des deux
A code> et
b code>.
@David Rodríguez - Dribesas: Omgomgomg. Tu as raison! Je ne sais pas comment j'ai négligé ça. +1 pour le commentaire.