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 oluşturulur, ancak olarak oluşturulurCCustomException. MFC 2.5 ve önceki sürümlerdeki CATCH makrosu, çalışma zamanında türü test etmek için kullanırCObject::IsKindOf. Çünkü ifade

e->IsKindOf(RUNTIME_CLASS(CException));

true olduğunda, ilk catch bloğu özel durumu 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.

Bunun gibi kodlar sık karşılaşılan bir durumdur. Genellikle bir özel durum nesnesi genel CException*bir kabul eden başka bir işleve geçirildiğinde görünür, "önceden oluşturma" işlemi gerçekleştirir ve son olarak özel durum oluşturur.

Bu sorunu geçici olarak çözmek için throw ifadesini işlevden çağıran koda taşıyın ve özel durum oluşturulduğu sırada derleyici tarafından bilinen gerçek türde bir özel durum oluşturur.

Özel Durumları Yeniden Oluşturma

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

Ö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 . Özel Durumlar: Özel Durumları Yakalama ve Silme.

Ayrıca bkz.

Özel Durum İşleme