Pregunta

Tengo el siguiente 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;
      }
    }
};

Se supone que es un orden estrictamente débil, y es así de largo (podría ser solo una línea) para propósitos de depuración.

Estoy usando este functor como un comparador para un conjunto stl ::. El problema es que solo inserta el primer elemento. Al agregar la salida de la consola a la función de comparación, aprendí que en realidad se compara el nombre del archivo con él mismo cada vez .

Otras líneas relevantes son:

typedef set<SimulatedDiskFile *, ComparatorClass> FileSet;

y

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

EDITAR: el código que llama a .addFile () es:

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++;
}

Donde all_requests es una lista, y la Solicitud de clase es 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();
};

Desearía poder ofrecer mi hipotesis sobre lo que está sucediendo, pero en realidad no tengo idea. Gracias de antemano por cualquier puntero.

¿Fue útil?

Solución

No hay nada de malo en el código que has publicado, funcionalmente hablando. Este es un programa de prueba completo: solo he completado los espacios en blanco, sin cambiar el código en absoluto.

#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;
}

Obtengo esta salida:

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

Tenga en cuenta que el conjunto termina con las tres cosas almacenadas en él, y su registro de comparación muestra un comportamiento sensible.

Editar:

Tu error está en estas líneas:

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

disk.addFile(&temp_file);

Estás tomando la dirección de un objeto local. Cada vez que se recorre el bucle, el objeto se destruye y el siguiente objeto se asigna exactamente en el mismo espacio. Así que solo el objeto final aún existe al final del bucle y ha agregado múltiples punteros a ese mismo objeto. Fuera del bucle, todas las apuestas están desactivadas porque ahora no existe ninguno de los objetos.

O asigne cada SimulatedDiskFile con nuevo (como en mi prueba, pero luego tendrá que averiguar cuándo eliminarlos), o no use punteros (mucho más fácil si se ajusta a las restricciones de su problema) ).

Otros consejos

Y aquí está el problema:

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

Está agregando un puntero a una variable que se destruye inmediatamente. Necesita crear dinámicamente sus 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 quedaría fuera de alcance en el momento de la siguiente iteración en el ciclo while. Necesita cambiar el código de inserción. Cree objetos SimulatedDiskFile en el montón y presione de lo contrario si los objetos son más pequeños, luego almacene por valor en el conjunto.

De acuerdo con @Earwicker. Todo se ve bien. ¿Has echado un vistazo dentro de todas las solicitudes? ¿Quizás todos los nombres de archivo son iguales y todo lo demás funciona bien? (solo pensando en voz alta aquí)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top