Переменная std :: string не сохраняет свое значение - PullRequest
0 голосов
/ 13 января 2019

Итак, у меня есть std :: list класса, и я добавляю объекты его производных классов (например, «Discus» - это производный класс «Item»). У меня есть несколько std::string переменных, и я инициализирую это в конструкторе. Чтобы std::string переменные были получены через std::cin, я поместил такие переменные прямо в конструктор. Например. «имя» и «материал», которые получают через std::cin, это просто std::string. Так что у него есть некоторые ценности. Но когда я выхожу из этой функции, ее значения пусты (это как ""). Что может вызвать эту проблему? Я предполагаю, что переменные 'name' и 'material' удаляются, но я не уверен, правда ли это и как избавиться от этой проблемы. Извините, если этот вопрос довольно глуп, спасибо за любую помощь.

class Discus : public Throwable, public Material {
public:
    Discus(int, int, int, std::string*, std::string*);
    void setMaterial(std::string*);
    void setType();
    std::string info();
};

class Storage {
private:
    std::list<Item*> storage;
public:
    std::list<Item*>* getStorage();
    void addItem(Item*);
    void showInfo();
};

Это реализация функции, которую я использую для добавления элементов:

void addItem(Storage* store) {
bool to_continue = true;
while (to_continue) {
    std::cout << "What to add?\n1)Discus\n2)Javelin\n3)Hammer\n4)Dumbbell\n5)Kettlebell\n6)Barbell\0 для to exit\n";
    int key = -1;
    std::cin >> key;
    if (key > 0 && key < 7) {
        int parameters[3];
        std::cout << "Enter price, amount of items, the weight of an item\n";
        for (int i = 0; i < 3; i++) std::cin >> parameters[i];
        std::string name;
        std::string material;
        int len = 0;
        std::cout << "Enter name:\n";
        std::cin >> name;
        switch (key) {
        case 1: {
            std::cout << "Enter a name of material:\n";
            std::cin >> material;
            Discus d(parameters[0], parameters[1], parameters[2], &material, &name);
            Discus* it = &d;
            (*store).addItem(it);
            break;  
        }
        case 2: {
            std::cout << "Enter a name of material:\n";
            std::cin >> material;
            std::cout << "Enter a length:\n";
            std::cin >> len;
            (*store).getStorage()->push_back(&Javelin(parameters[0], parameters[1], parameters[2], &material, len, &name));
            break; 
        }
        case 3: {
            std::cout << "Enter a name of material:\n";
            std::cin >> material;
            std::cout << "Enter a length:\n";
            std::cin >> len;
            (*store).getStorage()->push_back(&Hammer(parameters[0], parameters[1], parameters[2], &material, len, &name));
            break;
        }
        case 4:
        {(*store).getStorage()->push_back(&Dumbbell(parameters[0], parameters[1], parameters[2], &name)); break; }
        case 5: {
            std::cout << "Enter a name of material:\n";
            std::cin >> material;
            (*store).getStorage()->push_back(&Kettlebell(parameters[0], parameters[1], parameters[2], &material, &name));
            break;
        }
        case 6: {
            std::cout << "Enter a length:\n";
            std::cin >> len;
            (*store).getStorage()->push_back(&Barbell(parameters[0], parameters[1], parameters[2], len, &name));
            break;
        }
        }
    }
    else if (key == 0) 
        to_continue = false;
    else std::cout << "Sorry, try one more time\n";
}
}

1 Ответ

0 голосов
/ 13 января 2019

Основная причина этого заключается в том, что объект может умирать, когда он выходит из области видимости.

Кажется, ваша ситуация выглядит примерно так:

...
    if (key > 0 && key < 7) {
        ...
        std::string name;
        std::string material;
        ...
        switch (key) {
        case 1: {
            ...
            Discus d(parameters[0], parameters[1], parameters[2], &material, &name);
            Discus* it = &d;
            (*store).addItem(it);
            break;  
        } // d will die here. So, pointer it will become dangling
    } // name and material will die here. So, pointers to them will become dangling.

Вы можете использовать const std::string & для своих целей вместо std::string *. Для объекта класса Discus вместо использования указателя raw вы можете перейти к unique_ptr.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...