2012-09-06 9 views
0

J'apprends le C++ et j'essaie d'en apprendre plus sur l'utilisation du clavier ami.Comment utiliser les classes imbriquées correctement en C++?

Toutefois, j'ai des problèmes pour utiliser des classes imbriquées dans mon fichier d'en-tête. Je sais que les fichiers d'en-tête ne doivent être utilisés que pour les déclarations, mais je ne voulais pas y inclure un fichier cpp, donc j'ai simplement utilisé un fichier d'en-tête pour déclarer et construire.

De toute façon, j'ai un fichier main.cpp que je veux strictement utiliser pour créer des objets de classes et accéder à ses fonctions.

Cependant, je ne sais pas exactement comment créer la fonction FriendFunctionTest dans mon fichier d'en-tête où je peux y accéder dans mon fichier source main.cpp en utilisant l'objet Class d'en-tête parce que j'essaie de comprendre le mot-clé "friend" .

Voici mon code d'en-tête:

#ifndef FRIENDKEYWORD_H_ 
#define FRIENDKEYWORD_H_ 

using namespace std; 

class FriendKeyword 
{ 
    public: 
     FriendKeyword() 
     {//default constructor setting private variable to 0 
      friendVar = 0; 
     } 
    private: 
     int friendVar; 

    //keyword "friend" will allow function to access private members 
    //of FriendKeyword class 
    //Also using & in front of object to "reference" the object, if 
    //using the object itself, a copy of the object will be created 
    //instead of a "reference" to the object, i.e. the object itself 
    friend void FriendFunctionTest(FriendKeyword &friendObj); 
}; 

void FriendFunctionTest(FriendKeyword &friendObj) 
{//accessing the private member in the FriendKeyword class 
    friendObj.friendVar = 17; 

    cout << friendObj.friendVar << endl; 
} 

#endif /* FRIENDKEYWORD_H_ */ 

Dans mon fichier main.cpp, je voulais faire quelque chose comme ceci:

FriendKeyword keyObj1; 
FriendKeyword keyObj2; 
keyObj1.FriendFunctionTest(keyObj2); 

Mais évidemment, sa ne va pas au travail depuis le principal. cpp ne peut pas trouver la fonction FriendFunctionTest dans le fichier d'en-tête.

Comment résoudre ce problème?

Et je m'excuse à nouveau, j'essaie juste d'apprendre le C++ en ligne.

+1

'FriendFunctionTest' n'est pas une fonction membre, vu que votre définition ne nécessite pas' FriendKeyword :: '. Qu'est-ce que ça a à voir avec 'keyObj1'? Pour élaborer, une fois que 'friend' est impliqué, la fonction n'a aucune possibilité d'être membre de cette classe, même si elle est définie à l'intérieur de la classe. – chris

+1

Pourquoi le tag Java? – Mysticial

+0

Ce n'est pas comme ça qu'un ami travaille. Il est généralement utilisé entre deux classes différentes et non deux instances différentes de la même classe. – ksming

Répondre

1

Le mot clé friend est uniquement utilisé pour spécifier si une fonction ou une autre classe peut avoir accès aux membres privés de cette classe. Vous n'avez aucun besoin d'héritage de classe ou d'imbrication car FriendFunctionTest est une fonction globale. Les fonctions globales ne nécessitent aucun préfixe de classe lorsqu'elles sont appelées.

Source pour friend: http://msdn.microsoft.com/en-us/library/465sdshe(v=vs.80).aspx

+0

merci monsieur! cela fonctionne maintenant, alors qu'est-ce qui rend une fonction globale? – user1631224

+0

@ user1631224: par "global", il signifie non-membre. –

+0

Les fonctions globales ne sont pas encapsulées dans un espace de noms ou une classe. – willkill07

0

Vous parlez vraiment plusieurs choses complètement différentes ici. Voici quelques exemples pour deux d'entre eux:

1) "Amis":

  • http://www.learncpp.com/cpp-tutorial/813-friend-functions-and-classes/

    // déclaration de classe classe {Accumulator privé: int m_nValue; public: Accumulateur() {m_nValue = 0; } void Ajouter (int nValue) {m_nValue + = nValue; }

    // Faire de la fonction Reset() un ami de cette classe friend void Reset (Accumulator & cAccumulator); };

    // Reset() est maintenant un ami de la réinitialisation vide de classe Accumulator (Accumulator & cAccumulator) {// Et peut accéder aux données privées des objets Accumulator cAccumulator.m_nValue = 0; }

2) "classes": emboîtées

0

Un ami est pas membre. Voici un bon exemple de la façon dont "ami" est utilisé dans la pratique.

namespace Bar { 

class Foo { 

    public: 
     // whatever... 

    friend void swap(Foo &left, Foo &right); // Declare that the non-member function 
              // swap has access to private section. 
    private: 
     Obj1 o1; 
     Obj2 o2; 
}; 

void swap(Foo &left, Foo &right) { 
    std::swap(left.o1, right.o1); 
    std::swap(left.o2, right.o2); 
} 

} // end namespace Bar 

Nous avons déclaré une fonction de permutation Foo qui est plus efficace que std :: swap serait, en supposant que les classes Obj1 et Obj2 ont-déplacer sémantique efficace. (Darn it, vous êtes rapide avec cette coche verte! :))

Il est utile de savoir que parce que la routine d'échange est paramétrée par un objet Foo (deux dans ce cas) et est déclaré dans le même espace de noms que Foo, ça devient une partie de l'interface publique de Foo, même si ce n'est pas un membre. Le mécanisme est appelé "recherche dépendant de l'argument" (ADL).

Questions connexes