Доступ к локальной переменной после “удаляет это”

У меня есть класс, который использует механизм подсчета ссылок. Объекты этого класса в конечном счете уничтожаются путем вызова 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();
    }
};
7
задан FireAphis 6 August 2010 в 09:44
поделиться

4 ответа

Да , , вы можете сделать это , , пока сама переменная-член действительно является только ссылкой на внешний объект.

(Простите за предыдущий неправильный ответ, меня смутила переменная mutex_ .)

7
ответ дан 7 December 2019 в 05:15
поделиться

Да, можно, но почему бы не использовать атомарное уменьшение вместо уменьшения счетчика под мьютексом? И действительно ли вам нужно защищать (путем мьютекса) разрушение объекта? Действительно, после того, как счетчик становится 0, единственный текущий поток может получить доступ к объекту.

Итак, возможно, можно переписать свой код как

     int tmp_count;
     m.Acquire();
        tmp_count= --recount_;
     m.Release();
     if (tmp_count <= 0)  delete this;

(или использовать атомики для уменьшения и проверки счетчика)

1
ответ дан 7 December 2019 в 05:15
поделиться

Да, в этом случае. Ваша переменная стека 'm' указывает на внешний ресурс, который вы получаете в конструкторе

0
ответ дан 7 December 2019 в 05:15
поделиться

Обычно единственное, что вам не разрешается вызывать после удаления этого , - это все, что ссылается на this . Это включает любой нестатический член или функцию класса.

В вашем случае велика вероятность, что RemoveReference не будет работать. Это потому, что m указывает на mutex_ , который больше не существует после удаления этого. Лучше всего сделать mutex_ статическим.

Редактировать: Хотя mutex_ указывает на внешнюю переменную, которая продолжает существовать после удаления класса, нет надежной гарантии, что компилятор не обратится к mutex_ ] после удаления класса, чтобы получить значение внешнего мьютекса. Есть хороший шанс, что все будет работать так, как ожидалось, но я не верю, что это можно гарантировать.

0
ответ дан 7 December 2019 в 05:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: