Временный указатель перед освобождением? - PullRequest
0 голосов
/ 09 мая 2020

Я изучил atlbase.h, чтобы увидеть, как реализован CComPtr<>, и наткнулся на функцию Release() в базовом классе CComPtrBase<>, которая освобождает нижележащий объект следующим образом:

// Release the interface and set to NULL
void Release() throw()
{
    T* pTemp = p;
    if (pTemp)
    {
        p = NULL;
        pTemp->Release();
    }
}

Мой интеллект недостаточно хорош, чтобы понять, в чем смысл этого временного указателя pTemp?

Почему этот код не просто:

   void Release() throw()
   {
       if (p)
       {
           p->Release();

           // EDIT:
           p = NULL;
       }
   }

Теперь, если вы посмотрите в деструкторе деструктор определяется так же, как и мои ожидания из приведенного выше примера, в чем разница?

1 Ответ

1 голос
/ 09 мая 2020

Здесь есть два возможных объяснения:

  1. Если p->Release() выбрасывает, то во втором варианте оно не будет установлено в NULL, а будет в первом. Обратите внимание, что включающая функция объявлена ​​throw(), поэтому она не должна генерировать исключения. Возможно, эта функция была написана до добавления спецификатора throw(). (Или, может быть, кодировщик используется для защитного кодирования в подобных ситуациях и использует общий шаблон.)
  2. Первый вариант может быть оптимизирован хвостовым вызовом, а второй - нет.
...