2009-06-16 83 views
0

我有以下函子:STL字符串比較函子

class ComparatorClass { 
    public: 
    bool operator() (SimulatedDiskFile * file_1, SimulatedDiskFile * file_2) { 
     string file_1_name = file_1->getFileName(); 
     string file_2_name = file_2->getFileName(); 

     cout << file_1_name << " and " << file_2_name << ": "; 

     if (file_1_name < file_2_name) { 
     cout << "true" << endl; 
     return true; 
     } 
     else { 
     cout << "false" << endl; 
     return false; 
     } 
    } 
}; 

它應該是一個嚴格弱序,它的這個長(可能是隻有一條線)進行調試。

我使用這個函數作爲stl :: set的比較函子。問題在於,它只插入第一個元素。通過將控制檯輸出添加到比較器功能中,我瞭解到它實際上每次都會將文件名進行比較。

其他相關的線路有:

typedef set<SimulatedDiskFile *, ComparatorClass> FileSet; 

// (FileSet files_;) <- SimulatedDisk private class member 
void SimulatedDisk::addFile(SimulatedDiskFile * file) { 
    files_.insert(file); 
    positions_calculated_ = false; 
} 

編輯:調用.addFile()的代碼是:

current_request = all_requests.begin(); 
while (current_request != all_requests.end()) { 
    SimulatedDiskFile temp_file(current_request->getFileName(), current_request->getResponseSize()); 
    disk.addFile(&temp_file); 
    current_request++; 
} 

凡all_requests是一個列表,並且類請求是這樣的:

class Request { 
    private: 
    string file_name_; 
    int response_code_; 
    int response_size_; 

    public: 
    void setFileName(string file_name); 
    string getFileName(); 
    void setResponseCode(int response_code); 
    int getResponseCode(); 
    void setResponseSize(int response_size); 
    int getResponseSize(); 
}; 

我希望我能提供我的假設,以瞭解發生了什麼,但我其實不知道。提前感謝任何指針。

+0

如果它看起來每次都比較相同的文件名,那麼它不會在第一個之後插入任何新成員,因爲對於集合來說,每個新文件都不會比較爲「小於」 '不大於'已經在集合中的一個文件。你從哪裏得到你傳入addFile方法的文件指針? – 2009-06-16 12:14:19

+0

調用addFile的代碼是什麼? – Patrick 2009-06-16 12:15:44

回答

5

從功能上講,您發佈的代碼沒有任何問題。這裏有一個完整的測試程序 - 我只填寫空格,根本不改變你的代碼。

#include <iostream> 
#include <string> 
#include <set> 

using namespace std; 

class SimulatedDiskFile 
{ 
public: 
    string getFileName() { return name; } 

    SimulatedDiskFile(const string &n) 
     : name(n) { } 

    string name; 
}; 

class ComparatorClass { 
    public: 
    bool operator() (SimulatedDiskFile * file_1, SimulatedDiskFile * file_2) { 
     string file_1_name = file_1->getFileName(); 
     string file_2_name = file_2->getFileName(); 

     cout << file_1_name << " and " << file_2_name << ": "; 

     if (file_1_name < file_2_name) { 
     cout << "true" << endl; 
     return true; 
     } 
     else { 
     cout << "false" << endl; 
     return false; 
     } 
    } 
}; 

typedef set<SimulatedDiskFile *, ComparatorClass> FileSet; 

int main() 
{ 
    FileSet files; 

    files.insert(new SimulatedDiskFile("a")); 
    files.insert(new SimulatedDiskFile("z")); 
    files.insert(new SimulatedDiskFile("m")); 

    FileSet::iterator f; 
    for (f = files.begin(); f != files.end(); f++) 
     cout << (*f)->name << std::endl; 

    return 0; 
} 

我得到這樣的輸出:

z and a: false 
a and z: true 
z and a: false 
m and a: false 
m and z: true 
z and m: false 
a and m: true 
m and a: false 
a 
m 
z 

注意,設置結束與存儲在它所有的三兩件事,和你比較日誌顯示明智的行爲。

編輯:

你的錯誤是在這些行:

SimulatedDiskFile temp_file(current_request->getFileName(), current_request->getResponseSize()); 

disk.addFile(&temp_file); 

你把本地對象的地址。每次在循環中該對象被銷燬並且下一個對象被分配到完全相同的空間中。所以只有最後一個對象仍然存在於循環結尾,並且你已經添加了多個指向同一對象的指針。在循環之外,所有投注都關閉,因爲現在沒有任何對象存在。

要麼爲每個SimulatedDiskFile分配新的(就像在我的測試中一樣,但是你必須找出何時刪除它們),否則根本不使用指針(如果它適合你的約束,問題)。

2

這裏的問題是:

SimulatedDiskFile temp_file(current_request->getFileName(), 
            current_request->getResponseSize()); 
disk.addFile(&temp_file); 

你加入一個指向它立即銷燬的變量。您需要動態創建您的SDF對象。

1
urrent_request = all_requests.begin(); 
while (current_request != all_requests.end()) { 
    SimulatedDiskFile temp_file(...blah..blah..); ====> pointer to local variable is inserted 
    disk.addFile(&temp_file); 
    current_request++; 

}

temp_file會走出去的範圍的時刻下一次迭代中while循環。您需要更改插入代碼。在堆上創建SimulatedDiskFile對象,如果對象較小,則按下其他按鈕,然後按值存儲在set中。

0

同意@Earwicker。一切看起來不錯。你有看看all_requests嗎?也許所有的文件名在那裏是一樣的,其他一切工作正常? (只是在這裏大聲思考)