Tengo un problema para el que no he encontrado una respuesta en una semana. Tengo una clase de matriz dinámica y tiene un método para agregarle valores de cadena. Se supone que representa un inventario al que puede agregar artículos. Sin embargo, encuentro que los cambios realizados en el método a los valores privados del elemento de clase no se "actualizan" cuando trato de llamar a un método de impresión para el elemento de clase "mochila" más adelante en el main (). Creo que esto podría ser un problema debido a problemas de referencia, pero he visto que esto funciona cuando una clase no ha estado en un módulo diferente.

Mi módulo "mochila" imprime y agrega métodos:

 const int INITIAL_SIZE = 5;
 Inventory::Inventory():
        array_(new string[INITIAL_SIZE]),
        max_space_(INITIAL_SIZE),
        used_space_(0) {}

 void Inventory::add(string item){

if ( size() == max_space_ ) {
    string* new_array = new string[2 * max_space_];

    for ( int i = 0; i < size(); ++i ) {
        new_array[i] = array_[i];
    }

    delete [] array_;

    array_ = new_array;
    max_space_ = 2 * max_space_;
}

array_[used_space_] = item;
++used_space_;
}

void Inventory::print() {

for ( int i = 0; i < size(); ++i ) {
    cout << array_[i] << endl;
}
}

El principal():

Inventory inv;
string input;

while (cout << "input> "
        and getline(cin,input)){

add_to_bag(input,inv);

Entonces, el punto es que reinicia el inventario cuando le da nuevos contenidos. La función add_to_bag (); es:

  void add_to_bag(string input, Inventory inv){

  const string WHITESPACE1_REGEX = "[[:space:]]*";
  const string WHITESPACE2_REGEX  = "[[:space:]]+";
  const string WORD_REGEX                      = "[[:alpha:]_]+";

  const string LINE_REGEX =
      WHITESPACE1_REGEX +
      WORD_REGEX +
      "(" +
      WHITESPACE2_REGEX +
       WORD_REGEX +
      ")*" +
      WHITESPACE1_REGEX;

regex line_reg(LINE_REGEX);
regex word_regex(WORD_REGEX);

string line = input;

    if ( regex_match(line, line_reg) ) {

        sregex_iterator iter(line.begin(), line.end(), word_regex);
        sregex_iterator end;

        while ( iter != end ) {
            inv.add(iter->str());
            ++iter;
        }

    } else {

        cout << "Error: unknown inventory contents." << endl;
    }
}
0
murtourpo95 13 dic. 2016 a las 17:47

2 respuestas

La mejor respuesta

Tu problema es:

    void add_to_bag(string input, Inventory inv);

Pasas una copia del objeto Inventory a add_to_bag. Modificas esa copia ... y luego se desecha. La solución es pasar por referencia:

    void add_to_bag(string input, Inventory &inv);

Por cierto, en el código de la vida real, recomendaría encarecidamente el uso de std::vector<std::string> en lugar de "rodar el tuyo". Hay una serie de problemas complicados de manejo de excepciones que se han equivocado aquí, y a menos que Inventory no tenga un destructor (lo que implica una pérdida de memoria), o tenga un constructor de copia correcto, habría esperado que se encontrara Problemas de "doble libre". (Lea sobre "La regla de tres").

6
Martin Bonner supports Monica 13 dic. 2016 a las 14:51

Una forma sencilla de diseñar tu clase sería la siguiente:

class Inventory {
private:
    std::vector<std::string> items_;

public:
    Inventory(){}
    ~Inventory(){}

    void addItem( const std::string& item ) {
       items_.push_back( item );
    }

    void printInventory() const {
        int idx = 0;
        for (; idx < items_.size(); ++idx ) {
            std::cout << items_[idx] << std::endl;
        }     
    }

    void clearInventory() {
        items_.clear();
    }
};

Y en cuanto a tu problema, Martin Bonner ya lo había respondido con la modificación de la copia y la eliminación de la misma después y los demás problemas con la gestión de la memoria.

0
Francis Cugler 13 dic. 2016 a las 15:11