Aracılığıyla paylaş


Özel Durumlar: Sürüm 3.0'da Özel Durum Makrolarındaki Değişiklikler

Bu gelişmiş bir konudur.

MFC sürüm 3.0 ve sonraki sürümlerinde, özel durum işleme makroları C++ özel durumlarını kullanacak şekilde değiştirilmiştir. Bu makalede, bu değişikliklerin makroları kullanan mevcut kodun davranışını nasıl etkileyebileceği açıklanabilir.

Bu makalede aşağıdaki konular ele alınır:

Özel Durum Türleri ve CATCH Makro

MFC'nin önceki sürümlerinde , CATCH makrosu bir özel durumun türünü belirlemek için MFC çalışma zamanı türü bilgilerini kullanıyordu; özel durumun türü, başka bir deyişle catch sitesinde belirlenir. Ancak C++ özel durumlarında, özel durumun türü her zaman throw sitesinde, atılan özel durum nesnesinin türüne göre belirlenir. Bu durum, atılan nesnenin işaretçi türünün, atılan nesnenin türünden farklı olduğu nadir durumlarda uyumsuzluklara neden olur.

Aşağıdaki örnekte, MFC sürüm 3.0 ile önceki sürümler arasındaki bu farkın sonucu gösterilmektedir:

TRY
{
   THROW((CException*) new CCustomException());
}
CATCH(CCustomException, e)
{
   TRACE("MFC 2.x will land here\n");
}
AND_CATCH(CException, e)
{
   TRACE("MFC 3.0 will land here\n");
}
END_CATCH

Bu kod sürüm 3.0'da farklı davranır çünkü denetim her zaman eşleşen bir özel durum bildirimiyle ilk catch bloğa geçer. Throw ifadesinin sonucu

THROW((CException*) new CCustomException());

CException* olarak atılır, ancak CCustomException olarak oluşturulmuştur. MFC 2.5 ve önceki sürümlerdeki CATCH makrosu, çalışma zamanında türü test etmek için kullanır CObject::IsKindOf . Çünkü ifade

e->IsKindOf(RUNTIME_CLASS(CException));

doğru olduğunda, ilk catch bloğu istisnayı yakalar. Özel durum işleme makrolarının birçoğunu uygulamak için C++ özel durumlarını kullanan sürüm 3.0'da ikinci catch bloğu, atılan ile eşleşir CException.

Bu tür kodlar sık rastlanmaz. Genellikle bir istisna nesnesi, genel CException* bir kabul eden başka bir işleve geçirildiğinde görünür, "ön işleme" işlemi gerçekleştirir ve son olarak istisnayı fırlatır.

Bu sorunu aşmak için atış ifadesini işlevden çağrıcı koda taşıyın ve özel durum oluşturulduğunda derleyici tarafından bilinen gerçek türde bir özel durum atın.

Re-Throwing İstisnalar

Bir catch bloğu, yakaladığı özel durum işaretçisinin aynısını fırlatamaz.

Örneğin, bu kod önceki sürümlerde geçerliydi, ancak sürüm 3.0 ile beklenmeyen sonuçlara sahip olacaktır:

TRY
{
   // Do something to throw an exception.
   AfxThrowUserException();
}
CATCH(CException, e)
{
   THROW(e);    // Wrong. Use THROW_LAST() instead
}
END_CATCH
   }

Yakalama bloğunda THROW kullanılması işaretçinin e silinmesine neden olur, böylece dış yakalama sitesi geçersiz bir işaretçi alır. yeniden atmak eiçin THROW_LAST kullanın.

Daha fazla bilgi için bkz İstisnalar: İstisnaları Yakalama ve Silme.

Ayrıca bakınız

Özel Durum İşleme