У меня часто возникают проблемы с правильностью констант при переносе алгоритмов в классах в c++. Я чувствую, что хочу изменяемую функцию, хотя это запрещено. Может кто-нибудь посоветовать мне, как реализовать классы, такие как следующий?
Ниже приведен код, который я хочу написать.
- Функция run() не должна быть константная функция, потому что она меняет данные.
- Функция get_result() должна быть постоянной функцией (насколько это касается пользователя), потому что она возвращает данные.
Однако, если пользователь запрашивает результат без вызова run(), я хочу, чтобы функция get_result() запускала алгоритм. Это нарушает правильность const, потому что у меня есть const-функция, вызывающая неконстантную функцию.
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() в const-функцию get_result() и сделайте переменные данных изменяемыми.
Насколько я понимаю, ключевое слово mutable было разработано для третьей из этих опций, где реализация требует изменения данных, но пользователь разумно ожидает простой возврат и, следовательно, функцию const.
Однако я не хочу делать этот последний вариант, потому что я хочу, чтобы пользователь мог точно выбирать, когда они изменяют данные. Однако есть вероятность, что они забудут вызвать run(), и поэтому я хочу принудительно запустить алгоритм, если они запросят результат без вызова run(). Я чувствую, что хочу сделать run() изменчивым, но мне нельзя.
Как правильно написать такой класс?