STL comparação de string functor
Pergunta
Eu tenho o seguinte functor:
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;
}
}
};
É suposto ser uma ordenação fraco estrito, e é esse longo (pode ser apenas uma linha) para fins de depuração.
Estou usando este functor como um functor de comparação para uma STL :: set. Problema ser, ele só insere o primeiro elemento. Ao adicionar a saída do console para a função de comparação, eu aprendi que ele é realmente comparando o nome do arquivo para si sempre .
Outras linhas relevantes são:
typedef set<SimulatedDiskFile *, ComparatorClass> FileSet;
e
// (FileSet files_;) <- SimulatedDisk private class member
void SimulatedDisk::addFile(SimulatedDiskFile * file) {
files_.insert(file);
positions_calculated_ = false;
}
EDIT: o código que chama .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++;
}
Onde all_requests é uma lista, e Solicitação de classe é tal que:
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();
};
Eu gostaria de poder oferecer a minha Hipótese sobre o que está acontecendo, mas eu realmente não tenho idéia. Agradecemos antecipadamente por qualquer ponteiros.
Solução
Não há nada de errado com o código que você postou, funcionalmente falando. Aqui está um programa de ensaio -. Eu só preenchido os espaços em branco, não alterar seu código em tudo
#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;
}
Eu recebo esta saída:
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
Note que o conjunto acaba com todas as três coisas armazenadas nele, e seus comparação mostra madeireiras comportamento sensato.
Editar:
O seu erro é nestes linha:
SimulatedDiskFile temp_file(current_request->getFileName(), current_request->getResponseSize());
disk.addFile(&temp_file);
Você está tomando o endereço de um objeto local. Cada vez em torno do laço que objeto é destruído eo próximo objeto é alocado em exatamente o mesmo espaço. Assim, apenas o objeto final ainda existe no final do loop e você adicionou vários ponteiros para o mesmo objeto. Fora do loop, todas as apostas estão fora, porque agora nenhum dos objetos existe.
De qualquer alocar cada SimulatedDiskFile com o novo (como no meu teste, mas depois você vai ter que descobrir quando excluí-los), ou então não use ponteiros em tudo (muito mais fácil se ele se encaixa as limitações de seu problema ).
Outras dicas
E aqui está o problema:
SimulatedDiskFile temp_file(current_request->getFileName(),
current_request->getResponseSize());
disk.addFile(&temp_file);
Você está adicionando um ponteiro para uma variável que é imediatamente destruído. Você precisa criar dinamicamente seus objetos 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 iria sair do âmbito do momento próxima iteração no loop while. Você precisa mudar o código de inserção. Criar SimulatedDiskFile objetos no montão e empurre caso contrário, se os objetos são menores, em seguida, armazenar por valor em conjunto.
Concordo com @Earwicker. Tudo parece ser bom. Você já teve um olhar para dentro all_requests? Talvez todos os nomes de arquivos são os mesmos lá e tudo está funcionando bem? (Apenas pensando alto aqui)