C ++ - Alphabetizing Strings - '<'运算符重载

时间:2010-12-06 00:58:51

标签: c++ string operator-overloading alphabetical

首先,这是家庭作业,我对我应该做的事情有很好的理解,但我显然错过了一些东西。

我目前有一个名为“Person”的抽象基类。我有3个课程继承了他们的职员,教师和学生。

我正在尝试按姓氏组织所有“人”的名字。所以我必须重载'<'运营商。

我写了这个函数,但我不知道把它放在哪里。

功能:

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个相同的错误,这些错误都指向了这个函数。

错误:

'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 个答案:

答案 0 :(得分:4)

首先,您希望这适用于所有人,因此您应该将其置于人物中。你想比较任何两个人,所以RHS应该是人。

另外,你的逻辑是双重否定。我不知道为什么你会这样做,等等......

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

......更有意义。

答案 1 :(得分:2)

当您尝试在const对象上调用运算符时,可能会出现错误。编译器不知道operator<不会更改它所调用的对象,因此会出错。要确保函数不更改对象,请将函数声明为const

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

这样,也可以在常量对象上调用该函数。 getLastName()可能也应该是const

答案 2 :(得分:2)

看起来您可能需要添加或更改您的getter:

    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个getter,所以它根本不能使用任何getter!

答案 3 :(得分:1)

您应该将它放在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
}