【问题标题】:C++ - Alphabetizing Strings - '<' Operator OverloadC++ - 按字母顺序排列字符串 - '<' 运算符重载
【发布时间】:2010-12-06 00:58:50
【问题描述】:

对于初学者来说,这是家庭作业,我很清楚自己应该做什么,但我显然遗漏了一些东西。

我目前有一个名为“Person”的抽象基类。我有 3 个继承人的类,它们是 Staff、Faculty 和 Student。

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

函数我已经写好了,但我就是不知道放在哪里。

功能:

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(); 
    }

在听取了其他人的建议后,我只将这个功能放在了“Person”中,并使其不是虚拟的。然而,我仍然得到 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;

};

【问题讨论】:

  • 您的错误输出被切断。请发布整个错误消息。
  • 该错误与您的问题无关:msdn.microsoft.com/en-us/library/2s2d2tez%28VS.80%29.aspx getLastName 应该是const 成员函数。 (我猜getLastName 是非常量的,因为您的operator&lt; 是非常量)。
  • @Steve Jessop:你不知道错误与const-ness 相关,因为你看不到错误。您的链接仅表明该问题可能与 const-ness 有关。
  • @robert:有根据的猜测,如我的评论中所述。
  • 我已为我的问题添加了更新

标签: c++ string operator-overloading alphabetical


【解决方案1】:

首先,您希望它适用于所有人,因此您应该将它放在 Person 中。而你想比较任何两个人,所以 RHS 应该是人。

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

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

... 更有意义。

【讨论】:

  • 我改变了所有的东西,我只是把函数放在“Person”中,但我仍然得到 5 个指向同一行的相同错误。错误 1 ​​错误 C2662:“Person::getLastName”:无法将“this”指针从“const Person”转换为“Person &”——Johnny Whisman 0 秒前编辑
【解决方案2】:

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

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

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

【讨论】:

  • 太糟糕了,编译器没有推断出 constness。在我看来,有很多情况可以做到,包括这个。
【解决方案3】:

看起来您可能需要从以下位置添加或更改您的 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!

【讨论】:

    【解决方案4】:

    您应该将它放在您的 Person 类中,如果您无法想象派生类需要更改顺序,则它不需要是虚拟的。鉴于名称的排序似乎不会因 Person 的不同分类而有所不同,因此未指明 virtual

    参数应该是const Person&amp;,并且函数本身应该是const(把它放在{引入实现之前,或者 - 如果实现不合时宜,在尾随@987654325之前@。

    编辑:我在下面添加了一个实现。

    注意事项:

    • operator&lt; 是一个成员函数,因此可以访问私有成员变量而不需要通过公共成员函数(例如getLastName())。从某种意义上说,使用公共成员函数更好(由于实现更改而需要重写的可能性较小),但我在下面一直很懒,并使用了较短的直接访问。
    • 级联比较确保我们在LastNames 相等时比较其他字段,依此类推。最后比较 SSN,我假设它是唯一的,以确保即使是两个同名的人也会有一个可预测的、可重复的排序。如果您想为Person 对象设置“稳定”排序顺序,那么这是必不可少的,例如在std::map&lt;Person, XXX&gt; 中使用这些对象是必要的。将operator&lt; 写成这样稳定是一个很好的经验法则,尽管它往往有点冗长,有时执行起来可能会更慢。

    实施:

    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
    }
    

    【讨论】:

    • 我改变了所有的东西,我只是把函数放在“Person”中,但我仍然收到 5 个指向同一行的相同错误。
    • 错误 1 ​​错误 C2662: 'Person::getLastName' : 无法将 'this' 指针从 'const Person' 转换为 'Person &'
    • @Johnny Whisman:您更新后的代码未按照本答案第二段中的建议显示 const
    • @Johnny:你还需要把所有不设置/修改成员变量const的函数都做起来,这样才能保持一致并正常工作。为什么?因为如果你有一个const Person&amp;,那么你只能调用那个人的const成员函数……你需要调用GetLastName(),所以它也必须是const
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-16
    • 2017-02-23
    • 2015-05-07
    相关资源
    最近更新 更多