Некоторые вопросы по использованию CComPtr (при использовании Release ()? Могу ли я вернуть CComPtr ?, ...) - PullRequest
11 голосов
/ 26 ноября 2010

Я пишу надстройку для Internet Explorer (BHO) и использую умные указатели CComPtr.Интересно:

  1. Когда мне следует использовать функцию CComPtr.Release ()?
  2. Могу ли я безопасно вернуть CComPtr из функции?
  3. Разве я никогда не должен использовать нормальный указатель?

1 Ответ

17 голосов
/ 26 ноября 2010

К первому вопросу. CComPtr::Release() имеет тот же эффект, что и назначение нулевого указателя на объект.Вы можете вызвать Release() (или присвоить нулевой указатель), если по какой-либо причине вы хотите освободить объект до , указатель выходит из области видимости.Например:

CComPtr<ISomeInterface> pointer;
HRESULT hr = firstProvider->GetObject( &pointer );
if( SUCCEEDED( hr ) ) {
   //use the object
   pointer.Release();
}
HRESULT hr = secondProvider->GetObject( &pointer );
if( SUCCEEDED( hr ) ) {
   //use the object
}

Видите ли, когда GetObject() получает указатель, он перезаписывает значение, уже сохраненное в CComPtr.Если CComPtr хранит ненулевой указатель, он будет просто перезаписан (поверхностное копирование), а объект, на который указывает исходный указатель, будет пропущен.Вам не нужно Release() перед первым GetObject() - указатель в этом месте нулевой.И вам не нужно ни после второго GetObject() - объект будет возвращен, как только указатель выйдет из области видимости.

На второй вопрос Да, вы можете вернуть CComPtr, но только если вызывающий абонент также принимает его в CComPtr.Следующий код:

ISomeInterface* pointer = YourFunctionReturningCComPtr();

не будет владеть объектом, поэтому объект будет освобожден и pointer станет висящим.Это неопределенное поведение.

К третьему вопросу CComPtr относится к собственности.Обычно нет смысла передавать CComPtr в качестве параметра «in», если вы не знаете, почему именно вы это делаете.

...