C ++ - Алфавитные строки - '<' Перегрузка оператора - PullRequest
1 голос
/ 06 декабря 2010

Для начала, это домашняя работа, я хорошо понимаю, что я должен делать, но я явно что-то упускаю.

В настоящее время у меня есть абстрактный базовый класс под названием "Person". И у меня есть 3 класса, которые наследуют человека, это сотрудники, преподаватели и студенты.

Я пытаюсь упорядочить все имена людей по фамилии. Поэтому я должен перегрузить оператор «<». </p>

У меня написана функция, но я просто не знаю, где ее поставить.

Функция:

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

Должен ли я поместить это в файл заголовка для всех моих производных классов или в виртуальную функцию в базовом классе Person? Или я должен сделать оба. В настоящее время я делаю оба, и я получаю сообщение об ошибке для каждого файла.

ошибка:

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

Обновление: Я изменил свою функцию на:

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

Получив совет от других людей, я только поместил эту функцию в «Персона» и сделал ее не виртуальной. И все же я получаю 5 таких же точных ошибок, которые все указывают на эту функцию.

Error

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

Если это кому-нибудь поможет, вот код моего "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;

};

Ответы [ 4 ]

4 голосов
/ 06 декабря 2010

Во-первых, вы хотите, чтобы это работало на всех людях, поэтому вы должны поставить это лично И вы хотите сравнить любые два человека, поэтому RHS должен быть человеком.

Кроме того, ваша логика является двойным негативом. Я не уверен, зачем ты это сделал, когда ...

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

... имеет больше смысла.

2 голосов
/ 06 декабря 2010

похоже, вам может понадобиться добавить или изменить ваши геттеры с:

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

на

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

Это потому, что функция, выдающая вам ошибки, не имеет изменяемойверсия экземпляра Person, но нет const геттеров, поэтому он вообще не может использовать никаких геттеров!

2 голосов
/ 06 декабря 2010

Ошибка, которую вы получаете, вероятно, возникает при попытке вызова оператора для объекта const.Компилятор не знает, что operator< не изменяет объект, к которому он вызван, и поэтому выдает ошибку.Чтобы функция не изменяла объект, объявите функцию как const:

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

Таким образом, функция также может быть вызвана для постоянных объектов.getLastName() вероятно также должно быть const.

1 голос
/ 06 декабря 2010

Вы должны поместить его в свой класс Person, и он не должен быть виртуальным, если вы не представляете производный класс, которому нужно изменить порядок.Учитывая, что сортировка имен, похоже, не является чем-то отличающимся для разных категорий Person, virtual не указывается.

Аргумент должен быть const Person&, а сама функция должна бытьсделал const (поместите это непосредственно перед { введением реализации, или - если реализация выходит за рамки, перед завершающим ;.

РЕДАКТИРОВАТЬ: я добавил реализацию ниже.

Обратите внимание:

  • operator< является функцией-членом, поэтому может получать доступ к закрытым переменным-членам без необходимости проходить через публичные функции-члены (например, getLastName()).функции-члены более хороши в одном смысле (меньше шансов на необходимость переписывания из-за изменений в реализации), но я был ленив ниже и использовал более короткий прямой доступ.
  • Каскадные сравнения, чтобы гарантировать, что мы сравниваем с другимиполя, когда LastName s равны, и т. д. Это заканчивается сравнением SSN, который, как я полагаю, является уникальным, чтобы убедиться, что даже два человека сТо же имя будет иметь предсказуемый, повторяемый порядок.Это важно, если вы хотите иметь «стабильный» порядок сортировки для Person объектов, например, необходимо использовать эти объекты в std::map<Person, XXX>.Хорошим эмпирическим правилом было бы написать operator<, чтобы быть стабильным, как это, хотя это имеет тенденцию быть немного более многословным и иногда может выполняться медленнее.

Реализация:

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
}

... еще один популярный способ написать это ...

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
}
...