2010-12-06 4 views
1

Für den Anfang ist dies Hausaufgaben, ich habe ein gutes Verständnis von dem, was ich tun soll, aber ich vermisse offensichtlich etwas.C++ - Alphabetische Strings - '<' Operator Overload

Ich habe derzeit eine abstrakte Basisklasse namens "Person". Und ich habe 3 Klassen, die Person erben, die Personal, Fakultät und Student sind.

Ich versuche, alle "Person" Namen mit Nachnamen zu organisieren. Also muss ich den '<'-Operator überladen.

Ich habe die Funktion geschrieben, aber ich weiß nur nicht, wo ich es hinstellen soll.

Funktion:

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

Soll ich dies in der Header-Datei für alle meine abgeleiteten Klassen, oder sollte ich es als eine virtuelle Funktion in der Basisklasse Person? Oder soll ich beides machen? Momentan mache ich beides und bekomme für jede Datei einen Fehler.

Fehler:

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

Update: Ich habe meine Funktion geändert:

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

Nachdem ich Ratschläge von anderen Menschen, ich habe diese Funktion nur platziert in „Person "und machte es nicht virtuell. Dennoch bekomme ich immer noch 5 genau die gleichen Fehler, die auf diese Funktion hinweisen.

Fehler:

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

Wenn es jemand hilft überhaupt hier ist der Code zu meinem "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

Ihre Fehlerausgabe ist abgeschnitten. Bitte posten Sie die gesamte Fehlermeldung. – robert

+0

Der Fehler ist nicht wirklich auf Ihre Frage bezogen: http://msdn.microsoft.com/en-us/library/2s2d2tez%28VS.80%29.aspx 'getLastName' sollte eine' const' Member-Funktion sein. (Ich nehme an, dass 'getLastName' nicht-const ist, weil Ihr' operator <'nicht-const ist). –

+0

@Steve Jessop: Sie wissen nicht, dass der Fehler sich auf 'const'-ness bezieht, weil Sie den Fehler nicht sehen können. Ihr Link deutet lediglich darauf hin, dass das Problem sich auf "const" bezieht. – robert

Antwort

2

Der Fehler, den Sie wahrscheinlich bekommen tritt auf, wenn Sie versuchen, auf eine der Betreiber anrufen const Objekt. Der Compiler weiß nicht, dass operator< das Objekt, an dem es aufgerufen wird, nicht ändert und daher einen Fehler gibt. Um sicherzustellen, dass die Funktion das Objekt nicht ändern, erklären die Funktion als const:

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

Auf diese Weise kann die Funktion auch auf konstante Objekte aufgerufen werden. getLastName() sollte wahrscheinlich auch const sein.

+0

Schade, dass der Compiler keine Constness ableitet. Es scheint mir, dass es viele Fälle gibt, wo es könnte, einschließlich dieser. –

4

Erstens wollen Sie dies auf alle Menschen arbeiten, , also solltest du es in Person bringen. Und Sie wollen zwei Personen vergleichen, also sollte die RHS Person sein.

Auch Ihre Logik ist doppelt negativ. Ich bin nicht sicher, warum Sie das tun würden, wenn ...

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

... macht viel mehr Sinn.

+0

Ich änderte all das Zeug und ich habe nur die Funktion in "Person", aber ich bekomme immer noch 5 der gleichen Fehler zeigen auf die gleiche genaue Zeile. Fehler 1 Fehler C2662: 'Person :: getLastName': kann 'diesen' Zeiger nicht von 'const Person' in 'Person &' umwandeln - Johnny Whisman vor 0 Sek. Bearbeiten – Johnrad

1

Sie sollten es in Ihre Person-Klasse einfügen, und es muss nicht virtuell sein, wenn Sie sich nicht vorstellen können, dass eine abgeleitete Klasse die Reihenfolge ändern muss. Gegebene Sortierung von Namen scheint nicht etwas zu sein, das für die verschiedenen Kategorisierungen von Person abweichen würde, virtual ist nicht angegeben.

sollte das Argument ein const Person& sein, und die Funktion selbst sollte const (setzen, dass nur gemacht werden, bevor die { die Umsetzung der Einführung oder - wenn die Umsetzung ist aus der Reihe, vor dem ; Hinter

EDIT. : Ich habe unten eine Implementierung hinzugefügt.

Dinge zu beachten:

  • operator< eine Elementfunktion ist, so private Membervariablen, ohne Member-Funktionen öffentlich (z getLastName()) zu durchlaufen zugreifen können. Die Verwendung von public member-Funktionen ist in einer Hinsicht netter (weniger Möglichkeit, aufgrund von Implementierungsänderungen neu geschrieben zu werden), aber ich war unten faul und habe den kürzeren direkten Zugriff verwendet.
  • Die kaskadierenden Vergleiche, um sicherzustellen, dass wir auf andere Felder vergleichen, wenn LastName s gleich sind, und so weiter. Dies schließt mit dem Vergleich der SSN, von der ich annahm, dass sie einzigartig ist, um sicherzustellen, dass sogar zwei Personen mit demselben Namen eine vorhersehbare, wiederholbare Reihenfolge haben. Das ist wesentlich, wenn Sie eine "stabile" Sortierreihenfolge für Person Objekte, z. notwendig, diese Objekte in einem std::map<Person, XXX> zu verwenden. Es ist eine gute Faustregel, operator< zu schreiben, um so stabil zu sein, obwohl es dazu neigt, ein bisschen mehr wortreich zu sein und manchmal langsamer auszuführen ist.

Umsetzung:

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 
} 

... eine weitere beliebte Art des Schreibens ist dies ...

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

Ich habe all das geändert und habe einfach die Funktion eingefügt in "Person", aber ich bekomme immer noch 5 der gleichen Fehler, die auf dieselbe Linie zeigen. – Johnrad

+0

Fehler Fehler C2662: 'Person :: getLastName': kann 'diesen' Zeiger nicht von 'const Person' in 'Person &' umwandeln – Johnrad

+0

@Johnny Whisman: Ihr aktualisierter Code zeigt nicht die 'const' wie in empfohlen der zweite Absatz dieser Antwort. –

2

es sieht aus wie Sie benötigen, um aus Ihrem Getter hinzuzufügen oder zu ändern:

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

in

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

Dies liegt daran, die Funktion, die Sie eine Fehlermeldung nicht über eine veränderbare Version des Person-Instanz, aber es gibt keine const Getter, so kann es überhaupt keine Getter verwenden!