Правильная альтернатива «изменяемой функции» в c ++

У меня часто возникают проблемы с правильностью констант при переносе алгоритмов в классы на c ++. Я чувствую, что мне нужна изменяемая функция, хотя это не допускается. Может ли кто-нибудь посоветовать мне, как реализовать классы, подобные приведенному ниже?

Ниже приведен код, который я хочу написать .

  • Функция run () не должна быть const, потому что она изменяет данные.
  • Функция get_result () должна быть постоянной функцией (с точки зрения пользователя), потому что она возвращает данные.

Однако, если пользователь запрашивает результат без вызова run (), я хочу, чтобы функция get_result () запускала алгоритм. Это нарушает корректность констант, потому что у меня есть константная функция, вызывающая неконстантную функцию.

class operate_on_data
{
  std::vector<double> m_data;  // the data to modify
  bool m_completed;  // check to see if the function run() has been called
public:
  operate_on_data(std::vector<double> data)
    : m_data(data), m_completed(false) {}  //initialise
  void run() //I don't want this function to be const  
  {
    //The algorithm goes here - it alters m_data.
    m_completed = true;  //the algorithm has been run
  }
  std::vector<double> get_result() const //I want this function to be const
  {
    /*The following breaks const correctness because 
      I am calling a non-const function from a const function
      - but this feels like the right thing to do ... */ 
    if (!m_completed) run();  //run the algorithm if it has not run already
    return m_data; //return
  }
};

Единственный способ, которым мне удалось скомпилировать вышеуказанный класс, - это либо

  • сделать run () const, либо сделать m_data и m_completed изменяемый. Это работает, но концептуально неверно, потому что run () явно изменяет данные.
  • сделать get_result () не постоянной функцией. Это тоже кажется неправильным, поскольку пользователь ожидал бы, что эта функция будет простым возвратом и, следовательно, постоянной.
  • Поместите функцию run () в константную функцию get_result () и сделайте переменные данных изменяемыми.

Насколько я понимаю, ключевое слово mutable было разработано для третьей из этих опций, где реализация требует изменения данных, но пользователь разумно ожидает простого возврата и, следовательно, функции const.

Однако я не хочу использовать этот последний вариант, потому что хочу, чтобы пользователь мог выбирать, когда именно они изменяются данные. Однако есть вероятность, что они забудут вызвать run (), поэтому я хочу принудительно использовать алгоритм, если они запрашивают результат без вызова run (). Я чувствую, что хочу сделать run () изменяемым, но мне это не разрешено.

Как правильно написать такой класс?

14
задан valiano 29 July 2019 в 11:26
поделиться