Les opérateurs de surcharge sont une fonction de membre ou une fonction de non-membre (ami)?
Je suis en train de créer une classe utilitaire qui ont opérateurs surchargés. Quels sont les avantages et les inconvénients de faire de leur membre ou non-membre (friend
) fonctions? Ou est-il question? Peut-être qu'il est préférable pour cela?
source d'informationauteur Seth
Vous devez vous connecter pour publier un commentaire.
Chaque opérateur a ses propres considérations. Par exemple, le << opérateur (lorsqu'il est utilisé pour les flux de sortie, pas de décalage de bits) obtient un ostream comme premier paramètre, donc il ne peut pas être un membre de votre classe. Si vous êtes à la mise en œuvre de l'opérateur d'addition, vous aurez probablement envie de profiter de conversions de type automatique sur les deux côtés, donc vous allez aller avec un non-membre, etc...
Que pour permettre la spécialisation par le biais de l'héritage, un modèle commun est de mettre en œuvre un non-membre de l'opérateur en termes d'une fonction membre virtuelle (par exemple, l'opérateur<< appels virtuel de la fonction print() sur l'objet est transmis).
J'irais avec un "C++ Normes de Codage: 101 Règles, des lignes Directrices et des Pratiques Exemplaires": si vous pouvez le faire en tant que non-membre de la fonction, de le faire en tant que non-membre de la fonction (dans le même espace de noms).
L'une des raisons: il fonctionne mieux avec les implicites de conversion de type. Un Exemple: Vous avez un complexe de classe avec une surcharge de l'opérateur*. Si vous voulez écrire 2.0 * aComplexNumber, vous avez besoin de l'opérateur* pour un non-membre de la fonction.
Une autre raison: moins de couplage. Non-membre-fonctions moins étroitement couplée que les fonctions de membres. C'est presque toujours une bonne chose.
Si vous envisagez sur la mise en œuvre de streaming opérateurs (<< et >>) alors ils seront non-membres de méthodes parce que votre objet ne se trouve sur la gauche de l'opérateur.
Si vous envisagez sur la mise en œuvre ->, () ou [] ils sont naturellement méthodes membres.
Pour les autres (comparaison et mathématiques), vous devriez vérifier Coup de pouce.Les opérateursça aide vraiment.
Par exemple, si vous voulez mettre en œuvre les opérateurs suivants:
Vous n'avez qu'à écrire:
Le 2
operator+
sera automatiquement généré comme les non-membres qui vous permettra de bénéficier de conversions automatiques. Et ils seront mis en œuvre de manière efficace en terme deoperator+=
si vous écrivez du code qu'une seule fois.Si vous êtes à la mise en œuvre de l'op, alors très probablement vous avez besoin pour mettre en œuvre l'op=. c'est à dire si vous êtes en surcharge d'opérateur+, alors vous devriez mettre en œuvre +=.
Assurez-vous que vous êtes de retour const à un objet si vous faites de la post-incrémentation ou la surcharge opérateur+.
Donc, si vous avez une surcharge de l'opérateur + , puis le mettre en œuvre en tant que non-membre de l'exploitant et d'utiliser l'opérateur += à l'intérieur. Pour eg.
Pour les opérateurs binaires, une limitation des fonctions de membre est l'objet de gauche doit être de votre type de classe. Ceci permet de limiter l'utilisation de l'opérateur de manière symétrique.
Envisager une simple classe string:
Si vous mettez en œuvre l'opérateur+ comme une fonction membre, tandis que
str("1") + "2"
compiler,"1" + str("2")
ne compilera pas.Mais si vous mettez en œuvre l'opérateur+ comme un non-membre de la fonction, puis les deux de ces déclarations légales.
Il n'y a rien comme les pratiques exemplaires, mais cela dépend de l'opérateur de surcharge ..
Pour l'e.g .
>> et << ne peut pas être surchargé que les fonctions de membres .
Supposons que vous voulez faire comme ceci : obj1 = 2 * obj2 puis aller pour non-membre de la fonction.
Pour binaire de surcharge d'opérateur fonction membre ne prend que 1 paramètre (en invoquant l'objet est impcliitly passé ) tandis que les non-membres en fonction prend 2 paramètres .