@FaulerAffe
-

Почему после вызова деструктора unordered_map перестаёт работать?

У меня есть вот такой класс:
class accauntant: public position
{
private:
    unordered_map<string, float> stakes;
public:
    ~accauntant() {stakes.clear(); name.clear(); surname.clear(); patronymic.clear(); salary = 0;}
    float getStake(position employee)
    {
        if(stakes.find(employee.getName() + employee.getSurname() + employee.getPatronymic()) != stakes.end())
            return stakes[employee.getName() + employee.getSurname() + employee.getPatronymic()];
        else
            return 0;
    }
    void setStake(position employee, float f)
    {
        stakes[employee.getName() + employee.getSurname() + employee.getPatronymic()] = f;
    }
    void addEmp(position employee)
    {
        stakes[employee.getName() + employee.getSurname() + employee.getPatronymic()] = 1;
    }
    float calculateSalary(position employee)
    {
        return stakes[employee.getName() + employee.getSurname() + employee.getPatronymic()] * employee.getSalary();
    }
};

Вот класс position:
class position
{
protected:
    string name, surname, patronymic;
    int salary;
public:
    position(){salary = 0;}
    position(string n, string s, string p, int sal)
    {
        name = n;
        surname = s;
        patronymic = p;
        salary = sal;
    }
    string getName() const
    {
        return name;
    }
    string getSurname() const
    {
        return surname;
    }
    string getPatronymic() const
    {
        return patronymic;
    }
    int getSalary() const
    {
        return salary;
    }
    void setName(string n)
    {
        name = n;
    }
    void setSurname(string s)
    {
        surname = s;
    }
    void setPatronymic(string p)
    {
        patronymic = p;
    }
    void setSalary(int s)
    {
        salary = s;
    }
};

Если я явно вызываю деструктор объекта класса accauntant, то, когда я вызываю функцию addEmp (предварительно я заново заполнил аргумент этой функции значениями), программа вылетает с ошибкой. Если не очищать unordered_map с помощью clear, то всё равно ничего не работает. Если не вызывать деструктор аргумента этой функции, но вызывать деструктор обхекта класса accauntant, то тоже ничего не работает. Видимо проблема именно в деструкторе accauntant. Деструктор по заданию можно и не вызывать, всё и без него работает, но всё-таки хотелось бы понять, в чём именно проблема. Ошибка: Thread 1: EXC_BAD_ACCESS (code=1, address=0x0).
  • Вопрос задан
  • 61 просмотр
Решения вопроса 1
@Mercury13
Программист на «си с крестами» и не только
Как в анекдоте (явно времён 70-х, когда между Гондурасом и Сальвадором была Футбольная война).
— Что-то меня беспокоит Гондурас.
— Так не чеши его.

Вызов деструктора каскадно вызовет деструкторы всех полей, и это приведёт к тому, что на месте u_m будет мусор вроде nullptr и висячих указателей.

Автодеструкторы — важнейшая фишка Си++, отличающая его от других языков, и явный вызов деструктора нужен крайне редко, когда мы хотим чуть более ручное управление памятью. Вот пример из нашего проекта. Есть выделенный кусок памяти, и мы хотим уничтожить там объект и на его месте создать новый, не отдавая-выделяя память. Считаем, что объекты одинаковые, иначе вся магия пропадёт.
wiTile->~WiTile();
new (wiTile) WiTile(client(), icons, clazz, tileSettings(i));

В проекте на сотни тысяч строк я нашёл 34 таких места в библиотеках, в основном RapidJson, и три места собственно в программе.

Если хотите полностью очистить — делайте отдельную функцию clear.

Кстати, в вашем случае явно прописанный деструктор не нужен вообще. Вызываемые автоматически деструкторы полей сделают всё, что надо, чтобы корректно уничтожить его.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы