2010-12-06 33 views
1

Pour les débutants, c'est un devoir, j'ai une bonne compréhension de ce que je suis censé faire mais il me manque évidemment quelque chose. J'ai actuellement une classe de base abstraite appelée "Person". Et j'ai 3 classes qui héritent la personne elles sont le personnel, la faculté, et l'étudiant. J'essaie d'organiser tous les noms de «personne» par nom de famille. Je dois donc surcharger l'opérateur '<'.C++ - Chaînes d'alphabétisation - '<' Surcharge d'opérateur

J'ai la fonction écrite mais je ne sais pas où la mettre.

Fonction:

bool operator < (const Faculty &right) 
     { 
      if(getLastName() >= right.getLastName() == 0) 
       return true; 
      return false; 
     } 

Dois-je mettre cela dans le fichier d'en-tête pour toutes mes classes dérivées, ou devrais-je le mettre en fonction virtuelle dans la personne de classe de base? Ou devrais-je faire les deux. Actuellement, je fais les deux et je reçois une erreur pour chaque fichier.

erreur:

error C2662: 'Person::getLastName' : cannot convert 'this' pointer from 

Mise à jour: J'ai changé ma fonction:

bool operator < (const Person &right) 
    { 
     return LastName >= right.getLastName(); 
    } 

Après avoir obtenu des conseils d'autres personnes, je n'ai placé cette fonction dans « Personne "et l'a rendu non virtuel. Pourtant, je reçois toujours 5 des mêmes erreurs exactes qui pointent toutes vers cette fonction.

Erreur:

'Person::getLastName' : cannot convert 'this' pointer from 'const Person' to 'Person &' 

Si elle aide qui que ce soit ici le code à mon "Person.h":

class Person 
{ 
    private: 
     string FirstName, 
       LastName, 
       MiddleName, 
       SSN; 

     string FullName; 

    public: 
     Person(); 
     Person(string, string, string, string); 
     Person(string); 

     string getFirstName(); 
     string getLastName(); 
     string getMiddleName(); 
     string getSSN(); 
     string getFullName(); 

     void setFirstName(string); 
     void setLastName(string); 
     void setMiddleName(string); 
     void setSSN(string); 
     void setFullName(string); 

     virtual string getIdentity() 
     { 
      return FirstName + " " + MiddleName + " " + LastName + " " + SSN; 
     } 

     bool operator < (const Person &right) 
     { 
      return LastName >= right.getLastName(); 
     } 

     virtual string getPurpose() = 0; 

}; 
+0

Votre sortie d'erreur est coupée. S'il vous plaît poster l'intégralité du message d'erreur. – robert

+0

L'erreur n'est pas vraiment liée à votre question: http://msdn.microsoft.com/en-us/library/2s2d2tez%28VS.80%29.aspx 'getLastName' devrait être une fonction membre' const'. (Je suppose que 'getLastName' est non-const sur la base que votre' operator <'est non-const). –

+0

@Steve Jessop: vous ne savez pas que l'erreur se rapporte à 'const'-ness, car vous ne pouvez pas voir l'erreur. Votre lien suggère simplement que le problème peut se rapporter à 'const'-ness. – robert

Répondre

2

L'erreur que vous obtenez probablement se produit lorsque vous essayez d'appeler l'opérateur sur un const objet. Le compilateur ne sait pas que operator< ne change pas l'objet sur lequel il est appelé et donne donc une erreur. Pour vous assurer que la fonction ne change pas l'objet, déclarer la fonction comme const:

bool operator < (const Faculty &right) const { 
    ... 
} 

De cette façon, la fonction peut également être appelée sur des objets constants. getLastName() devrait probablement aussi être const.

+0

Dommage que le compilateur ne déduit pas constness. Il me semble qu'il y a beaucoup de cas où cela pourrait être le cas, y compris celui-ci. –

4

Tout d'abord, vous voulez que cela fonctionne sur tous les , donc vous devriez le mettre en personne. Et vous voulez comparer deux personnes, alors l'ERS devrait être une personne.

En outre, votre logique est un double négatif. Je ne sais pas pourquoi vous feriez cela, quand ...

bool operator < (const Person &right) 
     { 
      return getLastName() < right.getLastName(); 
     } 

... est beaucoup plus logique.

+0

J'ai changé tout ça et je viens de mettre la fonction dans "Personne" mais je reçois toujours 5 des mêmes erreurs pointant vers la même ligne exacte. Erreur 1 C2662: 'Person :: getLastName': impossible de convertir 'this' pointeur de 'const Person' à 'Person &' - Johnny Whisman Il ya 0 secondes modifier – Johnrad

1

Vous devriez le mettre dans votre classe Person, et il n'a pas besoin d'être virtuel si vous ne pouvez pas imaginer une classe dérivée ayant besoin de changer la commande. Étant donné le tri des noms ne semble pas être quelque chose qui serait différent pour les différentes catégorisations de la personne, virtual n'est pas indiqué.

L'argument doit être un const Person&, et la fonction elle-même doit être fait const (mis que juste avant la { introduction de la mise en œuvre, ou - si la mise en œuvre est hors de la ligne, avant le ; arrière

EDIT. : J'ai ajouté une implémentation ci-dessous.

choses à noter:

  • operator< est une fonction membre, ne peut donc accéder à des variables membres privées sans avoir besoin de passer par les fonctions membres du public (par exemple getLastName()). L'utilisation des fonctions membres publiques est plus agréable dans un sens (moins de chance d'avoir besoin d'être réécrit en raison des changements d'implémentation), mais j'ai été paresseux ci-dessous et j'ai utilisé l'accès direct plus court.
  • Les comparaisons en cascade pour assurer que nous comparons sur d'autres champs lorsque LastName s sont égaux, et ainsi de suite. Ceci conclut en comparant le SSN, que je suppose être unique, pour s'assurer que même deux personnes avec le même nom auront un ordre prévisible et reproductible. C'est essentiel si vous voulez avoir un ordre de tri "stable" pour les objets Person, par ex. nécessaire d'utiliser ces objets dans un std::map<Person, XXX>. C'est une bonne règle d'écrire operator< pour être stable comme ça, même si elle a tendance à être un peu plus verbeuse et peut parfois être plus lente à exécuter.

Mise en œuvre:

bool operator<(const Person& right) const 
{ 
    return LastName < right.LastName ? true : 
      LastName > right.LastName ? false : 
      FirstName < right.FirstName ? true : 
      Firstname > right.FirstName ? false : 
      MiddleName < right.MiddleName ? true : 
      MiddleName > right.MiddleName ? false : 
      SSN < right.SSN; // assume SSN is guaranteed unique 
} 

... Une autre façon populaire d'écrire c'est ...

bool operator<(const Person& right) const 
{ 
    return LastName < right.LastName || 
      LastName == right.LastName && 
       (FirstName < right.FirstName || 
       Firstname == right.FirstName && 
        (MiddleName < right.MiddleName || 
        MiddleName == right.MiddleName && 
         SSN < right.SSN)); // assume SSN is guaranteed unique 
} 
+0

J'ai changé tout ça et je viens de mettre la fonction dans "Personne" mais je reçois toujours 5 des mêmes erreurs pointant vers la même ligne exacte. – Johnrad

+0

Erreur erreur C2662: 'Person :: getLastName': impossible de convertir 'this' pointeur de 'const Person' en 'Personne &' – Johnrad

+0

@Johnny Whisman: Votre code mis à jour n'affiche pas le 'const' comme recommandé dans le deuxième paragraphe de cette réponse. –

2

il semble que vous pourriez avoir besoin d'ajouter ou de modifier vos apporteurs de:

string getFirstName(); 
    string getLastName(); 
    string getMiddleName(); 
    string getSSN(); 
    string getFullName(); 

dans

string getFirstName() const; 
    string getLastName() const; 
    string getMiddleName() const; 
    string getSSN() const; 
    string getFullName() const; 

En effet, la fonction génère des erreurs ne dispose pas d'une version mutable du Instance de personne, mais il n'y a pas de getters const, donc il ne peut pas utiliser de getters du tout!