2010-09-02 52 views
0

我有一個對象 - 員工,我想知道如何將此對象插入到按char * lastName字段排序的地圖結構中。感謝名單。 我的地圖需要包含指向Employee對象的指針,而不是對象本身。關鍵是員工的姓氏,地圖需要按員工的姓氏排序,我應該使用multimap嗎?如何通過某個字段將對象插入到地圖結構中?

+1

你可以通過使用'的std ::地圖:: insert'功能插入。 – 2010-09-02 13:53:22

+5

考慮使用'std :: string'而不是'char *'來存放字符串。 – 2010-09-02 13:55:02

+0

從您的評論中,您聽起來像是需要使用'char *'。你還需要使用'map'還是可以使用'set'? – 2010-09-02 14:22:31

回答

2

所以你已經有了一個帶自定義比較函數的std :: map(你已經重載了less運算符)並且你想插入對象以便它們按正確的順序?

myMap.insert(make_pair(myKey, myEmployee)); 

其中myKey是您的地圖的關鍵。然而,從你的問題的聲音,它實際上聽起來像你使用的對象,因爲它是自己的關鍵。在這種情況下,只需使用std ::設置和

mySet.insert(myEmployee); 

我也建議您不要使用char*作爲存儲lastName的和喜歡的std :: string的手段。

編輯:

繼意見樓下,你有能在一個const char*傳遞到另一個函數?如果是這樣,仍然使用string,因爲它有一個很好的方法.c_str()專門用於傳統兼容性。它可以這樣使用:

void stuffHappens(const char* _input){ 
    //magic happens in here 
} 

stuffHappens(myString.c_str()); 

和瞧,你更安全!

+0

Thanx爲快速回復,第一個是我需要的,關鍵是員工的姓。當然,我會使用這個字符串,但不幸的是它在我的工作中是不允許的。 – 2010-09-02 14:00:31

+0

@羅伊,你應該提到這是一個家庭作業問題。請將問題標記爲「家庭作業」。 – wilhelmtell 2010-09-02 14:02:50

+0

好的。我會提到的。 – 2010-09-02 14:08:15

1

定義bool operator <(const Employee& other)Employee類。或者,將bool operator <(const Employee& left, const Employee& right)定義爲非成員函數,並將其設爲friendEmployee。第一種方法的優點是它在Employee本地,並且增強了封裝。後一種方法的優點是它可以與可轉換爲Employee的任何兩種類型一起使用。或者,您可以創建一個比較器函子,而不是operator <(),並傳遞該地圖的構造函數。

最後,使用成員函數std::map<>插入新員工。 std::map<>也定義了operator [](),它允許你插入到地圖中。如果元素已經在地圖中,則insert()函數不會插入元素,而operator []()將在元素已存在的情況下更新該元素。

+0

如果他使用的是一個在char *上鍵入的映射,那麼重載<或創建一個函數並不是真的有必要。如果他切換到一套(這聽起來像他可能想),那麼這是有道理的。 – 2010-09-02 14:03:27

+1

@Niki,但他的地圖沒有鍵入'char *'。這是'僱員'的關鍵。 – wilhelmtell 2010-09-02 14:04:51

+0

@wilhelmtell - 他的問題有點模棱兩可。這聽起來像是他想要一張僱員的姓氏地圖,而不是其他人的地圖(如果情況是絕對正確的話)。很有可能他應該切換到「設置」,在這種情況下,你也完全正確。 – 2010-09-02 14:09:07

1

您可以創建一個覆蓋operator()的「函子」,並引用兩個對象並返回一個布爾值obj1 < obj2

例如:

class EmployeeComparator 
{ 
    public: 
    bool operator()(const Employee& emp1, const Employee& emp2) 
    { 
     return strcmp(emp1.lastName, emp2.lastName) < 0; 
    } 
} 

當您創建的std ::地圖,然後通過EmployeeComparator作爲比較對象,像這樣:重寫<

std::map<Employee, T, EmployeeComparator> m; 

其他海報的想法運算符也可以工作,但用這種方法你可以選擇一個標準來排序。按照我的方式,您可以有一張按姓氏排序的地圖,另一張按員工ID排序的地圖等。每張地圖都會通過與您的分揀機不同的功能。

請記住,以我的方式,如果您嘗試按私人字段進行排序,請將您的排序仿函數聲明爲要排序的類的朋友類。

1

要添加到wheaties所說的內容,如果Employee對象包含自己的密鑰,則應該使用set。爲了使用該集合,您將不得不明確定義一個Employee對象的比較方法。有兩種方法這樣做的,無論是定義操作<的對象:

class Employee 
{ 
public: 
    bool operator<(const Employee &rhs) 
    { 
    return strcmp(lastName, rhs.lastName) < 0; 
    } 
... 
}; 

,也可以定義你告訴一組用於比較的仿函數:

struct EmployeeLessThan 
{ 
    bool operator()(const Employee &lhs, const Employee &rhs) 
    { 
    return strcmp(lhs.lastName, rhs.lastName) < 0; 
    } 
}; 

std::set<Employee, EmployeeLessThan> myEmployees; 

編輯:一個VERY要記住的重要一點是set將其全部項目存儲爲const。它這樣做是因爲對set中元素的更改可能會更改元素的順序,並且set無法檢測到這一點並重新排序。如果你想更新集合中包含的任何員工,這可能會有問題。解決此問題的最佳方法是聲明您可能想更改爲mutable的Employee的任何數據成員。這會讓你改變它們的值,即使它是const

編輯2:如果您決定繼續使用地圖並且密鑰爲char *,那麼請記住,默認情況下,地圖將通過指針的值而不是指向它們的字符串來比較兩個char * 。在這種情況下最好的做法是使用std::string而不是char *。或者,你可以定義一個函數對象傳遞給地圖:

struct CharStarLessThan 
{ 
    bool operator()(const char *lhs, const char *rhs) 
    { 
    return strcmp(lhs, rhs) < 0; 
    } 
}; 

std::map<char *, Employee, CharStarLessThan> myEmployees; 
1

菲利普·波特寫的評論,你應該definetely使用std::string。因爲在你的CPP代碼幾個地方/文件聲明兩個不同char*不會具有相同的地址!由於char *不過是一個整數,所以對於一個且只有一個相同的姓氏,您將擁有多個char *鍵,而這不是您想要的。

走這條路:

std::map<std::string,YourType> yourMap; 
std::string strMyLastName = "Rolland"; 
YourType aValue; 
yourMap[strMyLastName ] = aValue; 
+0

我不能使用字符串。 – 2010-09-02 14:40:36

+0

@羅伊,請你爲什麼不能使用std :: string? ? ?當我告訴你,你將有相同姓氏的重要主菜時,我真的很認真。如果你編寫C++,儘可能使用std :: strings而不是char *,除非被迫做相反的事情。 – 2010-09-02 15:33:50

+0

我比你更生氣,這是我強迫我們做這件事的愚蠢的助教。 「lastName必須是char *,所有其他字段都可以是字符串」 – 2010-09-02 15:44:40

相關問題