2011-11-04 78 views
13

例如:在C++頭文件中,如果我定義了一個struct Record,我想用它進行排序,以便我想重載less operator。以下是我在各種代碼中注意到的三種方法。我大致注意到:如果我打算將Record放入一個std::set,map, priority_queue,...容器,版本2的作品(也可能是版本3);如果我要將Record存入vector<Record> v,然後撥打make_heap(v.begin(), v.end())等。那麼只有版本1可以工作。C++少運算符重載,使用哪種方式?

struct Record 
    { 
     char c; 
     int num; 

     //version 1 
     bool operator <(const Record& rhs) 
     { 
     return this->num>rhs.num; 
     } 

     //version 2 
     friend bool operator <(const Record& lhs, const Record& rhs) //friend claim has to be here 
     { 
     return lhs->num>rhs->num; 
     } 
    }; 
在例如同一頭文件

 //version 3 
     inline bool operator <(const Record& lhs, const Record& rhs) 
     { 
     return lhs->num>rhs->num; 
     } 

基本上,我想在這裏拋出的問題,看看是否有人能想出一些總結什麼是這三種方法之間的差異以及每個版本有什麼合適的地方?

+3

提高你的接受評級。 –

+0

可以請你發佈不適用的每個案例的完整示例程序 –

+2

我看不到版本3 –

回答

5

它們基本上是相同的,除非第一個是非const並且允許您修改它自己。

我喜歡第二個有2個原因:

  1. 這並不一定是一個friend
  2. lhs並不一定是一個Record
+0

我認爲第二個版本,如果你聲稱運營商<在班級定義內部,你必須聲稱它是該班級的朋友 – user268451

+0

@ user268451它不一定是朋友。如果它不是* 1,它實際上是最好的,因爲它會導致更好的封裝。 – Pubby

+0

@ Pubby8如果你想從一個類中定義一個自由函數,你必須添加'friend'。這與訪問私人會員無關。 – Sjoerd

-4

喜歡在課堂上,除非它不能在課堂上,因爲第一個參數是錯誤的類型。

+2

實際上,人們應該總是偏袒課外,以便適用左側和右側類型的轉換(而不僅僅是正確的轉換)。如果可能的話,使它成爲非朋友,那麼更好,因爲它將運營商從實現它的類中分離出來,僅僅根據公共接口。 –

+2

除非你是某種數字,否則你不想在比較運算符上進行轉換! – Joshua

+1

@Joshua並不總是如此,如果某個容器(map,sorted-set,...)需要它,你可以爲「非數字」類實現它。 – Kashyap

5

定義減少操作的最佳方式是:

struct Record{ 
    (...) 
    const bool operator < (const Record &r) const{ 
     return (num < r.num); 
    } 
}; 
+2

這不允許在左側進行轉換,所以絕對不是*最佳方式*。 – Sjoerd

+2

ipmlicit轉換的路徑是危險的,你不應該走 – g24l