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.

Foi útil?

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)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top