2009-10-12 617 views
3

我有学生对象的载体,我想用#include <algorithm>sort(list.begin(), list.end());问题重载<运算符在C++

为了做到这一点进行排序,我明白,我需要超负荷“<”操作,但后尝试(和失败)在网上建议的几种方法,我没有想法。

这里是我的最新尝试:

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

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

程序编译和运行,但我的操作功能排序过程中,不会被调用,当我试图比较两个Student对象像s1 < s2我得到了一个:

我该如何正确过载“错误没有发现超载运营商”这个操作符,这样我的排序将按我的意图工作?

回答

6

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

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

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

注意结尾的常量,这表明运营商<内,*这是不变的。

编辑我不能删除这个答案,因为它被接受了,但我会尽我所能。我也无法用一个正确的替换它。请参阅下面的Drew Dormanns评论,以及Ross Smiths answer

+0

我想我终于决定把它作为我会选择的答案,因为这是最直接导致我发现我的指针遇到的更大问题的答案。 –

+4

这种方法经常被避免,因为如果类型可转换为学生,代码将转换右侧类型,但不转换左侧类型。朋友功能对于双方来说都是一致的。 –

1

嗯,你可以做到这一点作为内部操作:

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

有了比较“这个”第二的实现。我脑海中的问题是:“名称”方法是否具有常规风格?因为如果没有,那么你不能写一个使用它的const方法。

+0

可能似乎 - 无论是“第一”,“第二”参数在朋友的版本是常量。 – Steve314

9

你没有说你正在使用哪种编译器,但我怀疑你使用的是一个相当新的实现“朋友不是声明”规则的编译器。类中的朋友声明不作为函数声明;其他包含Student.h的模块没有看到该函数的任何声明。它仅在Student.cpp文件中可见。 (较早的编译器没有此规则,并将朋友声明视为函数声明。)

函数不需要是朋友,因为它不使用任何Student类的私有成员(我假设名字()是公开的)。在类外部移动函数声明,并将“friend”替换为“extern”,并且它应该起作用。

可以使操作员成为一个成员函数,就像上面提到的一些海报一样,但这不是必须的。做比较运算符的成员函数通常会被忽视,因为它意味着两个参数不是对称对待的(一个是不可见的“this”参数,另一个是正常的函数参数),在某些情况下会导致令人惊讶的结果(例如,可以将不同类型的转换应用于参数)。

+0

是否需要标记函数声明extern?我只有每个人都在头文件中声明变量。 –

+0

这个很难决定一个答案。我最初的尝试都是在课堂上定义的,我只是在阅读别人声称“排序”不会影响的声明之后才尝试“朋友”版本,除非你这样做。原来我的确有一个指针相关的问题。 –

+0

的确,这不是真的必要;默认情况下,类外部的函数具有外部关联。我习惯于把它放入,以向读者表明函数是在另一个源文件中定义的(而不是在同一个文件中定义的函数的前向声明)。 –

2

顺便说一句,与函数这个简单的我个人只是这样做,除非风格指南禁止的类定义中的函数定义:

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

的“朋友”这种形式的声明让你限定非成员operator<类的身体内部。它仍然是朋友,所以Name()可以是私人的,如果需要的话。