Я читал некоторые сообщения на форуме, написанные давно, и столкнулись с проблемой, как это:вызов функции обратного вызова, когда объект будет уничтожен
Как создать объект такой, что вы можете передать функцию обратного вызова к нему, и когда объект уничтожается, функция обратного вызова всегда выполняется?
Я знаю, что эта функция обратного вызова должна быть помещена в деструктор с RAII. И у кого-то есть код решения этой проблемы, как указано ниже:
class MyClass {
public:
MyClass(void (*cb)()) : done(cb) {}
~MyClass() {
if (done) {
try {
(*done)();
}
catch (...) {
// choice of exit, log, throw an alert to somewhere in the
//system, or ignore
}
}
}
private:
void (*done)();
};
Но как-то я не чувствую себя комфортно с этим кодом.
- Поскольку часто советуют не
throw
в деструкторе, но это нормально здесь, по крайней мере в этом коде, так как весьtry
,catch
блок находится внутри деструктора? - Каким-то образом я чувствую, что нецелесообразно разыменовывать указатель в деструкторе, поскольку объект, на который указывает указатель, может быть в недопустимом состоянии во время разворачивания стека, когда еще есть еще одно исключение. Но в этом коде функция, на которую указывает функция, является функцией-членом, а в деструкторе проверяется этот указатель, так что это нормально в этом случае?
- Есть ли лучшее решение, чем этот код?
Err, деструктор * это * а Перезвони. – EJP
"*, поскольку объект, на который указывает указатель, может находиться в недопустимом состоянии во время разворачивания пакета, когда еще есть еще одно исключение *" - обратный вызов в этом примере принимает только отдельную функцию, а не объект, поэтому нет состояния объекта беспокоиться о. С другой стороны, обратный вызов может осуществлять внутренний доступ к другим объектам, но это другое дело. –
@RemyLebeau, вы думаете, это нормально, если деструктор вызывает указатель на функцию, который не является членом класса? – Allanqunzi