Если вам нужно выставить check_stuff
как общедоступный (а также do_something
, который в данный момент вызывает его), простой рефакторинг проведет вас без повторов каких-либо вычислений:
class Object {
public:
bool check_stuff() {
lock l(m);
return internal_check_stuff(l);
}
void do_something() {
lock l(m);
if (internal_check_stuff(l)) {
/* ... */
}
/* ... */
}
private:
mutex m;
bool internal_check_stuff(lock&) {
return /* some calculation */;
}
}
(согласно@ Ответ Логана, передача ссылки на блокировку внутренней функции - это просто хорошая идея, чтобы избежать забывчивости от будущих сопровождающих; -).
Рекурсивные блокировки необходимы только при вызове метода, который блокирует другой, который такжеделает (с той же блокировкой), но с небольшим рефакторингом (перемещение общей функциональности в частные методы, которые не блокируют, а принимают ссылки на блокировку как «напоминания» ;-) устраняет необходимость.
Нет необходимости повторятьлюбую функциональность - просто сделайте открытые функции, которые предоставляют точно такую же (блокирующую) функциональность, которая также необходима (неблокирующим образом, потому что блокировка уже получена) из других функций, в «полупустые оболочки», которые выполняют блокировку, затем вызывают такиечастные функции, которые выполняют всю необходимую работу.Другие функции в классе, которые нуждаются в такой функциональности, но хотят явно выполнять собственную блокировку, могут просто вызывать частные функции напрямую.