У меня есть класс, который использует механизм подсчета ссылок. Объекты этого класса в конечном счете уничтожаются путем вызова delete this
когда подсчет ссылок опускается до нуля. Мой вопрос: я могу использовать локальную переменную на стеке после delete this
? Вот более определенный пример:
class RefCountedClass
{
public:
RefCountedClass(Mutex& m) :
mutex_(m)
{}
.
.
.
private:
Mutex& mutex_;
void RemoveReference()
{
// As I understand, mutex_ will be destroyed after delete,
// but using m is all right because it is on-stack and
// references an external object. Am I right?
Mutex& m = mutex_;
m.Acquire();
--recount_;
if (refcount <= 0) delete this;
m.Release();
}
};
Да , , вы можете сделать это , , пока сама переменная-член действительно является только ссылкой на внешний объект.
(Простите за предыдущий неправильный ответ, меня смутила переменная mutex_
.)
Да, можно, но почему бы не использовать атомарное уменьшение вместо уменьшения счетчика под мьютексом? И действительно ли вам нужно защищать (путем мьютекса) разрушение объекта? Действительно, после того, как счетчик становится 0, единственный текущий поток может получить доступ к объекту.
Итак, возможно, можно переписать свой код как
int tmp_count; m.Acquire(); tmp_count= --recount_; m.Release(); if (tmp_count <= 0) delete this;
(или использовать атомики для уменьшения и проверки счетчика)
Да, в этом случае. Ваша переменная стека 'm' указывает на внешний ресурс, который вы получаете в конструкторе
Обычно единственное, что вам не разрешается вызывать после удаления этого
, - это все, что ссылается на this
. Это включает любой нестатический член или функцию класса.
В вашем случае велика вероятность, что RemoveReference
не будет работать. Это потому, что m
указывает на mutex_
, который больше не существует после удаления этого. Лучше всего сделать mutex_
статическим.
Редактировать: Хотя mutex_
указывает на внешнюю переменную, которая продолжает существовать после удаления класса, нет надежной гарантии, что компилятор не обратится к mutex_
] после удаления класса, чтобы получить значение внешнего мьютекса. Есть хороший шанс, что все будет работать так, как ожидалось, но я не верю, что это можно гарантировать.