问题超载< C ++中的运算符

时间:2009-10-12 01:52:07

标签: c++ operator-overloading

我有一个学生对象的向量,我想使用#include <algorithm>sort(list.begin(), list.end());

排序

为了做到这一点,我明白我需要重载“&lt;”运营商,但在尝试(和失败)网上建议的几种方法后,我的想法已经不多了。

这是我最近的尝试:

在Student.h ...

...
using namespace std;
class Student
{
    friend bool operator <(const Student& first, const Student& second);
    public:
    ...
    private:
    ...
};

在Student.cpp ......

...
#include "Student.h"
using namespace std;
...
bool operator <(const Student& first, const Student& second)
{
    return first.Name() < second.Name();
}

其中“Name()”是一个返回字符串的常量函数。

程序编译并运行,但我的操作符函数在排序期间从不被调用,当我尝试比较两个Student对象时,如s1 < s2我得到了一个“错误:找不到重载的操作符”

如何正确地重载此运算符,以便我的排序可以按照我的意图运行?

4 个答案:

答案 0 :(得分:9)

您没有说明您使用的是哪种编译器,但我怀疑您使用的是最近实施“朋友不是声明”规则的编译器。类中的friend语句不作为函数声明;包含Student.h的其他模块看不到该函数的任何声明。它只在Student.cpp文件中可见。 (较旧的编译器没有此规则,并将朋友声明视为函数声明。)

该函数不需要是朋友,因为它不使用Student类的任何私有成员(我假设Name()是公共的)。将函数声明移到类外,并将“friend”替换为“extern”,它应该可以工作。

可以使操作员成为成员函数,如上面提到的一些海报,但没有必要。使比较运算符成员函数通常不受欢迎,因为这意味着两个参数不是对称处理的(一个是不可见的“this”参数,另一个是正常的函数参数),在某些情况下会导致令人惊讶的结果(例如,可以对参数应用不同类型的转换。)

答案 1 :(得分:6)

我不会在这里使用朋友,我不确定它是否有效。我会用的是......

class Student
{
  public:
    bool operator< (const Student& second) const;
};

bool Student::operator< (const Student& second) const
{
  return (Name() < second.Name());
}

注意尾随const,表示在operator&lt;,*中这是常量。

编辑我无法删除此答案,因为它已被接受,但如果可以,我会这样做。我也无法用正确的替换它。请参阅下面的Drew Dormanns评论和Ross Smiths answer

答案 2 :(得分:2)

顺便说一句,使用函数这个简单的我个人会这样做,除非样式指南禁止在类定义中定义函数:

class Student
{
    friend bool operator <(const Student& first, const Student& second)
    {
        return first.Name() < second.Name();
    }
    ...
};

这种形式的“朋友”声明允许您在类的主体内定义非成员 operator<。它仍然是朋友,所以如果需要,Name()可以是私人的。

答案 3 :(得分:1)

好吧,你可以把它作为一个内部操作员:

class Student
{
    public:
    bool operator <(const Student& second) const;
    ...
    private:
    ...
};

将“this”与第二个进行比较。我心中的问题是:'Name'方法是否具有const风格?因为如果没有,那么你就不能编写一个使用它的const方法。