Как я могу проверить состояние объекта C ++ при доступе без дублирования - PullRequest
0 голосов
/ 06 ноября 2018

У меня есть объект C ++, работающий в отдельном потоке, и его состояние обновляется асинхронно. Код напоминает следующее:

class Controller : public Listener {
public:
    // Controller methods, to be called by the user from the main thread
    // My problem is that I am obliged to duplicate the call to validateState() in all methods
    void doAction1() {
        validateState(); // explicit call to validate state
    }
    void doAction2() {
        validateState(); // explicit call to validate state duplicated here and in every doActionX() method. 
    }
    ...

private:
    // Override Listener virtual methods(which are used as callbacks), called in an async manner
    void onXYZ() override;
    void onError(std::string) override { /* update m_error */ }
    ...

    // validate that no error has occurred
    void validateState() { 
        if(m_error) throw m_error;
    }

private:
    Error m_error; // updated 
};

Я подумал о решении перегрузить operator-> и вызвать validateState() один раз внутри, и таким образом удалить дублированные вызовы. Однако проблема заключается в том, что пользователь должен сделать controller->doAction1() и ему запрещено делать controller.doAction1().

Я также могу думать о других семантических проблемах с этим подходом:

  • Можно было бы ожидать, что перегрузка operator-> будет выполнена для проблем управления памятью (таких как наличие пользовательского распределителя), а не просто для какой-либо случайной операции.
  • отсутствие симметрии между -> и .

Дублирует ли вызов для validateState() на вновь добавленных методах ОК? Намерение избежать чрезмерно спроектированных конструкций.

Какой здесь был бы правдоподобный подход / дизайн?

1 Ответ

0 голосов
/ 06 ноября 2018

Вполне нормально, что все публичные функции класса вызывают одну и ту же приватную функцию. Ваша функция просто проверяет допустимость неявного параметра this, который совпадает с проверкой любого другого параметра

void Controller::doAction1(Arg1 arg1)
{
    // ensure preconditions hold
    validateState();
    validateArg1(arg1);

    // "real" code
}

void Controller::doAction2(Arg2 arg2, Arg3 arg3)
{
    // ensure preconditions hold
    validateState();
    validateArg2(arg2);
    validateArg3(arg3);

    // "real" code
}
...