Заменить объект shared_ptr другим - PullRequest
0 голосов
/ 23 июня 2018

В основном у меня есть базовый класс Employee с enum class внутри него и производные классы Worker, Intern, Manager с указанным полем из enum, описывающим их.

class Employee {
public:
    enum class Status {
        Intern,
        Worker,
        Manager
    };
protected:

    int employeeID;
    std::string Name;
    std::string Surname;
    int Salary;
    bool Hired;
...
}

class Worker : public Employee {

protected:

    Status status = Status::Worker;
}

// "Intern" and "Manager" same way.

Я храню объекты в vector<shared_ptr<Employee>> Firm; и изменяю их по ссылке sourceEmployee[index].

Что я хочу сделать, это:

Повышать / понижать в должности сотрудника, как? Я хочу найти указанного сотрудника и проверить его статус. Если это Worker, я хочу удалить Worker class объект и сделать вместо него объект Manager со всеми полями, сохраненными из Worker, такими как: имя, фамилия и т. Д.

Мой прототип (не работает) выглядит так:

    auto it = std::find_if(sourceEmployee.begin(), sourceEmployee.end(),
                      [&sourceEmployee, id](const auto &obj) { return obj->getID() == id; });
    auto index = std::distance(sourceEmployee.begin(), it);

        switch(sourceEmployee[index]->getStatus()) { // returning status

            case Intern::Status::Intern: // does it recognize object properly?

                auto tmp0 = std::move(*it);
                (*it).reset();                         // ??
                *it = std::make_shared<Worker>(tmp0);

                cout << "Employee " << id << " has been promoted" << endl;
                break;

1 Ответ

0 голосов
/ 24 июня 2018

Это то, что я вижу в вашем примере. Единственное отличие между Employee и его производными классами состоит в том, что каждый из производных классов имеет поле Status. Это поле служит той же цели во всех производных классах.
Вопрос: Почему производные классы? Просто сделайте status частью Employee и присвойте ему соответствующее значение, поскольку сотрудники повышаются и понижаются в должности. Тогда ответ на ваш вопрос заключается в том, что вы просто присваиваете status новое значение (предположительно, через метод класса).

Возможно, вы пропустили ключевые детали. Возможно, есть другие поля, поэтому есть причина иметь производные классы.
Вопрос , если status будет одинаковым для всех объектов класса, почему это не static const? (Даже тогда это похоже на дублирование данных. Возможно, есть лучший способ достичь вашей цели.)

Если вы хотите преобразовать один производный класс в другой, вы, вероятно, захотите определить конструктор для каждого производного класса, который принимает ссылку на базовый класс в качестве параметра. Это вызовет конструктор копирования в базовом классе, а затем инициализирует поля нового класса. (Если есть поля для копирования не в базовом классе, ваши данные организованы плохо.)

Worker::Worker(const Employee & person) : Employee(person) {}

Что касается вызова этого, то похоже, что вы ведете ненужную бухгалтерию, что может привести к ошибкам. Трудно сказать, так как ваш код неполон. Если предположить окружающий контекст, может сработать что-то вроде следующего:

it->reset(std::make_shared<Worker>(**it));

Конечно, правильный синтаксис зависит от того, как было объявлено it, и от того, как it было присвоено значение (ни один из которых не указан в вопросе).


Теперь давайте перейдем к улучшению организации данных. Возможно, вы обнаружите, что вместо производных от Employee было бы лучше иметь класс Job, из которого производные Intern, Worker и Manager. Тогда Employee может иметь (умный) указатель на Job, где будут храниться ваши данные, связанные с работой. Как преимущество, при переключении заданий копирование не требуется; просто удалите старый Job объект и выделите новый. (Это можно рассматривать как обобщение первого упомянутого мной случая, когда status просто присваивается новое значение.)

...