2009-10-12 235 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()可以是私人的,如果需要的話。