题
我有以下仿函数:
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是一个列表,而类Request是这样的:
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();
};
我希望我能说明发生了什么,但实际上我不知道。提前感谢任何指示。
解决方案
从功能上讲,您发布的代码没有任何问题。这是一个完整的测试程序 - 我只填写空白,而不是改变你的代码。
#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);
您正在获取本地对象的地址。每次围绕循环该对象被销毁,下一个对象被分配到完全相同的空间。因此,只有最终对象仍然存在于循环的末尾,并且您已经添加了多个指向同一对象的指针。在循环之外,所有赌注都已关闭,因为现在没有任何对象存在。
使用new分配每个SimulatedDiskFile(比如在我的测试中,但是你必须弄清楚何时删除它们),否则根本不使用指针(如果它符合您的问题的约束则更容易) )。
其他提示
问题在于:
SimulatedDiskFile temp_file(current_request->getFileName(),
current_request->getResponseSize());
disk.addFile(&temp_file);
您正在添加指向立即销毁的变量的指针。您需要动态创建SDF对象。
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中。
同意@Earwicker。一切看起来都不错你有没有看过all_requests?也许所有的文件名都是相同的,其他一切都运行正常? (只是在这里大声思考)