Я хочу иметь базовый класс, который имеет целью зарегистрировать его для обратного вызова (и де-регистрации в деструкторе), обратный вызов является чистой виртуальной функцией. Как это.правильный способ сделать абстрактный базовый класс, который регистрирует обратный вызов
struct autoregister {
autoregister() { callback_manager.register(this); }
~autoregister() { callback_manager.deregister(this); }
virtual void call_me()=0;
};
Но это кажется ненадежным для меня, я подозреваю, что в нем есть несколько условий гонки. 1) Когда callback_manager видит указатель, call_me все еще не поддается удалению, и он может занимать произвольное количество времени, пока объект не завершит конструкцию, 2) к тому времени, когда вызывается дерегистер, вызывается деструктор производного объекта, поэтому обратные вызовы должны не называть.
Одна из вещей, о которых я думал, заключалась в проверке внутри callback_manager, если указатель call_me действителен или нет, но я не могу найти стандартный способ получения адреса call_me или чего-то еще. Я думал о сравнении typeid (указатель) с typeid (autoregister *), но может существовать абстрактный класс inbetween, делая этот ненадежный, полученный: public middle {}; middle: public autoregister {} ;, конструктор середины может потратить час, например. загрузку SQL или поиск google, а обратный вызов видит, что это не базовый класс, и считает, что обратный вызов может быть вызван, и бум. Это можно сделать?
Q1: Есть ли другие условия гонки?
Q2: как это сделать (без условий гонки, неопределенного поведения и других ошибок) без запроса производного класса для регистрации регистра вручную?
Q3: как проверить, может ли виртуальная функция вызываться на указателе?
Хороший вопрос. Я всегда звоню на регистрацию и регистрирую мьютекс уровня экземпляра. – Bathsheba
Извините за downvote, но на основе ваших комментариев, то ясно, что это даже близко не ясно, о ваших реальных потребностях (и так как вы упорно утверждая, что ваши потребности не ответили, хотя вопросы вы подняли в комментариях были рассмотрены, кажется маловероятным, что вы сделали достаточно исследований, чтобы быть уверенными, чего вы действительно даже хотите). –
@JerryCoffin, пожалуйста, прочитайте вопрос, я, очевидно, заинтересован в решении на основе базового класса, по каким-либо причинам. До сих пор наиболее релевантный ответ на мой вопрос - единственный без кода, по user634175, другие ответы дают альтернативы, каждый из которых имеет разные компромиссы. Но голосуйте, как вам угодно, вашей прерогативой. Теперь я жду, чтобы увидеть, что-нибудь лучше, и я соглашусь, какой бы ответ ни был лучше. – Martin