Въпрос относно метода COM Release().

Научавам за COM и чета за този код:

    STDMETHODIMP_ (ULONG) ComCar::Release()
{
   if(--m_refCount==0) delete this;
   return m_refCount;
}

Въпросът ми е, ако m_refCount==0 и обектът са изтрити, как може променливата член на екземпляра m_refCount все още да съществува и да бъде върната? Моля, извинете ме, ако въпросът ми е толкова наивен, защото съм напълно начинаещ в COM. Много благодаря.

Свързана нишка е тук: Как може метод член да изтрие обекта?


person smwikipedia    schedule 22.02.2010    source източник
comment
съжалявам за това, gf. благодаря за напомнянето. :Д   -  person smwikipedia    schedule 22.02.2010


Отговори (2)


Вашето безпокойство е основателно, броят на реф трябва да бъде преместен в локална променлива, преди обектът да бъде изтрит.

STDMETHODIMP_ (ULONG) ComCar::Release()
{
   ULONG refCount = --m_refCount; // not thread safe
   if(refcount==0) delete this;
   return refCount;
}

Но дори този код все още е грешен, защото не е безопасен за нишки.

вместо това трябва да използвате код като този.

  STDMETHODIMP_ (ULONG) ComCar::Release()
  {
     LONG cRefs = InterlockedDecrement((LONG*)&m_refCount);
     if (0 == cRefs) delete this;
     return (ULONG)max(cRefs, 0);
  }
person John Knoeller    schedule 22.02.2010
comment
благодаря Джон, но имам някакво неловко усещане относно изтриването на обект в членския метод на ITS, как би могло това да е възможно? Ако обектът престане да съществува, как би могло да продължи изпълнението на неговия метод член? Чудя се дали това може да се обясни само чрез някои изследвания относно оформлението на обекта в паметта? - person smwikipedia; 22.02.2010
comment
@smwikipedia: Кодът за функциите съществува независимо от това дали екземплярът на класа съществува или не. Стековите променливи съществуват, докато не излезете от функцията. Така че няма проблем функцията да продължи да работи, след като екземплярът, който сме използвали, за да я извикаме, изчезне, стига да не се опитаме да докоснем данни от инстанция след изтриването. все още можете безопасно да докосвате статиките и стек променливите и кода. - person John Knoeller; 22.02.2010
comment
Просто направих експеримент. Написах метод на член с тялото като delet this и изпълнението не бе успешно. Изглежда, че има известна повреда в паметта. - person smwikipedia; 22.02.2010
comment
Здравей, Джон, можеш да видиш моя експериментален код тук: stackoverflow.com/questions/2309276/ - person smwikipedia; 22.02.2010
comment
@smwikipedia: вашият експеримент извиква delete на екземпляр, който никога не е бил new, което ще причини повреда на паметта. Нищо общо с факта, че извикването е в метод. ще получите същия резултат, ако замените извикването suicide с delete a - person John Knoeller; 22.02.2010

Сигурни ли сте, че функцията връща m_refCount?

Вярвам, че достъпът до членски променливи или методи след изтриване на обект е недефиниран според стандарта и никога не можете надеждно да направите това.

Единственият начин, по който мисля, че това може да работи, е ако методът Release() създаде локална променлива в стека с копие на броя на препратките и това се връща чрез оптимизиране на възвръщаемата стойност.

person LeopardSkinPillBoxHat    schedule 22.02.2010