2010-12-06 24 views
7

Que se passe-t-il lorsque vous faites d'une classe membre une fonction d'un ami ?!Rendre un membre fonctionnel est un ami

Le code ci-dessous compile et s'exécute. Sans la déclaration d'un ami, un «trop d'arguments à l'opérateur» est généré (et à juste titre). Je me rends compte que faire cela n'a aucun sens, mais quelqu'un peut-il me dire ce qui se passe ici? L'ami force-t-il le compilateur à omettre le paramètre par défaut de ce paramètre?

class Test 
{ 
public: 
    friend bool operator<(Test& lhs, Test& rhs) 
    { 
    return true; 
    } 
}; 

int main(int c, char** argv) 
{ 
    Test test1; 
    Test test2; 

    return test1 < test2; 
} 
+1

Pour répondre à votre question: Les amis ne peuvent pas être membres de la classe d'amitié en C++ 03, mais cela est autorisé en C++ 0x. –

+0

Je suis curieux, quel point pourrait-il y avoir de permettre à une fonction membre d'être une amie, puisqu'elle a déjà un accès complet? – radman

+0

Voir http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#77 ou l'historique (ce cas particulier n'a pas beaucoup d'importance, car les classes imbriquées ont un accès complet au classe d'imbrication dans C++ 0x et la plupart des compilateurs C++ 03 de toute façon). –

Répondre

9

La différence est qu'un ami n'est pas membre, même si la définition entière apparaît à l'intérieur de la classe; la fonction est plutôt placée dans l'espace de noms environnant. Donc, il n'y a pas de pointeur this. Alors qu'un membre operator< fonctionne implicitement sur this et l'argument explicite de droite, un argument friend a besoin des arguments de gauche et de droite fournis explicitement en tant que paramètres de fonction - d'où le paramètre supplémentaire. Votre version friend équivaut à mettre la fonction après la classe, sauf qu'elle a accès aux membres et bases private et protected et est implicitement inline (bien que cela ne signifie pas que le compilateur doit l'aligner - c'est seulement un indice, mais c'est important en ce qui concerne la règle de définition unique en ce sens que votre fonction friend peut être incluse dans de nombreuses unités de traduction et un lien sans problème).

1

Que se passe lorsque vous faites une fonction membre d'une classe un ami de lui-même !?

Cela n'a aucun sens. Comment une fonction membre d'une classe peut être un ami de la même classe?

Vous avez surchargé operator < en tant que fonction ami (pas en tant que fonction membre). Fournir la définition (corps) d'une fonction d'ami à l'intérieur de la classe est légal. Cependant, il est illégal d'utiliser this dans sa définition

friend bool operator<(Test& lhs, Test& rhs) 
{ 
    *this ; //error 
    return true; 
}