C++ dilinde yapılandırılmış özel durumları işleme
C yapılandırılmış özel durum işleme (SEH) ile C++ özel durum işleme arasındaki en önemli fark, C++ özel durum işleme modelinin türlerle ilgilenmesi, C yapılandırılmış özel durum işleme modelinin ise tek tür özel durumlarla ilgilenmesi; özel olarak, unsigned int
. Diğer bir ifadeyle, C özel durumları işaretsiz bir tamsayı değeriyle tanımlanırken, C++ özel durumları veri türüyle tanımlanır. C'de yapılandırılmış bir özel durum oluştuğunda, her olası işleyici C özel durum bağlamını inceleyen ve özel durumun kabul edilip edilmeyeceğini, başka bir işleyiciye geçirilip geçirileceğini veya yoksayılıp kabul edilmeyeceğini belirleyen bir filtre yürütür. C++ içinde bir özel durum oluştuğunda, herhangi bir türde olabilir.
İkinci bir fark, özel durumlar normal denetim akışına ikincil olarak gerçekleştiğinden C yapılandırılmış özel durum işleme modelinin zaman uyumsuz olarak adlandırılıyor olmasıdır. C++ özel durum işleme mekanizması tamamen zaman uyumludur, yani özel durumlar yalnızca oluşturulduklarında oluşur.
/EHs veya /EHsc derleyicisi seçeneğini kullandığınızda, hiçbir C++ özel durum işleyicisi yapılandırılmış özel durumları işlemez. Bu özel durumlar yalnızca yapılandırılmış özel durum işleyicileri veya __finally
yapılandırılmış sonlandırma işleyicileri tarafından __except
işlenir. Bilgi için bkz . Yapılandırılmış Özel Durum İşleme (C/C++).
/EHa derleyici seçeneği altında, C++ programında bir C özel durumu oluşturulursa, ilişkili filtresiyle yapılandırılmış bir özel durum işleyicisi veya özel durum bağlamına dinamik olarak daha yakın olan bir C++ catch
işleyicisi tarafından işlenebilir. Örneğin, bu örnek C++ programı bir C++ try
bağlamı içinde bir C özel durumu oluşturur:
Örnek - C++ catch bloğunda C özel durumu yakalama
// exceptions_Exception_Handling_Differences.cpp
// compile with: /EHa
#include <iostream>
using namespace std;
void SEHFunc( void );
int main() {
try {
SEHFunc();
}
catch( ... ) {
cout << "Caught a C exception."<< endl;
}
}
void SEHFunc() {
__try {
int x, y = 0;
x = 5 / y;
}
__finally {
cout << "In finally." << endl;
}
}
In finally.
Caught a C exception.
C özel durum sarmalayıcı sınıfları
Yukarıdaki gibi basit bir örnekte, C özel durumu yalnızca üç nokta (...) catch
işleyicisi tarafından yakalanabilir. Özel durumun türü veya doğası hakkında hiçbir bilgi işleyiciye iletilmemiştir. Bu yöntem çalışırken, bazı durumlarda her bir C özel durumunun belirli bir sınıfla ilişkilendirebilmesi için iki özel durum işleme modeli arasında bir dönüştürme tanımlamak isteyebilirsiniz. Birini dönüştürmek için, belirli bir sınıf türünü C özel durumuyla bağlamak için kullanılabilecek veya öğesinden türetilebilen bir C özel durum "sarmalayıcı" sınıfı tanımlayabilirsiniz. Bunu yaptığınızda, her C özel durumu tek bir işleyicide tümü yerine belirli bir C++ catch
işleyicisi tarafından ayrı ayrı işlenebilir.
Sarmalayıcı sınıfınız, özel durumun değerini belirleyen ve C özel durum modeli tarafından sağlanan genişletilmiş özel durum bağlam bilgilerine erişen bazı üye işlevlerinden oluşan bir arabirime sahip olabilir. Ayrıca, bir bağımsız değişkeni kabul eden (temel C özel durum gösterimini sağlamak için) ve bit tabanlı bir kopya oluşturucuyu kabul unsigned int
eden bir varsayılan oluşturucu ve oluşturucu da tanımlamak isteyebilirsiniz. C özel durum sarmalayıcı sınıfının olası bir uygulaması aşağıdadır:
// exceptions_Exception_Handling_Differences2.cpp
// compile with: /c
class SE_Exception {
private:
SE_Exception() {}
SE_Exception( SE_Exception& ) {}
unsigned int nSE;
public:
SE_Exception( unsigned int n ) : nSE( n ) {}
~SE_Exception() {}
unsigned int getSeNumber() {
return nSE;
}
};
Bu sınıfı kullanmak için, her C özel durumu oluşturulduğunda iç özel durum işleme mekanizması tarafından çağrılan özel bir C özel durum çevirisi işlevi yükleyin. Çeviri işlevinizin içinde, uygun bir eşleşen C++ catch
işleyicisi tarafından yakalanabilen herhangi bir türe sahip özel durum (belki bir SE_Exception
tür veya öğesinden SE_Exception
türetilmiş bir sınıf türü) oluşturabilirsiniz. Bunun yerine çeviri işlevi, özel durumu işlemediğini belirten döndürebilir. Çeviri işlevinin kendisi bir C özel durumu oluşturursa terminate çağrılır.
Özel bir çeviri işlevi belirtmek için, tek bağımsız değişken olarak çeviri işlevinizin adıyla _set_se_translator işlevini çağırın. Yazdığınız çeviri işlevi, blokları olan try
yığındaki her işlev çağrısı için bir kez çağrılır. Varsayılan çeviri işlevi yoktur; _set_se_translator çağırarak belirtmezseniz, C özel durumu yalnızca üç nokta catch
işleyicisi tarafından yakalanabilir.
Örnek - Özel çeviri işlevi kullanma
Örneğin, aşağıdaki kod özel bir çeviri işlevi yükler ve ardından sınıfı tarafından SE_Exception
sarmalanan bir C özel durumu oluşturur:
// exceptions_Exception_Handling_Differences3.cpp
// compile with: /EHa
#include <stdio.h>
#include <eh.h>
#include <windows.h>
class SE_Exception {
private:
SE_Exception() {}
unsigned int nSE;
public:
SE_Exception( SE_Exception& e) : nSE(e.nSE) {}
SE_Exception(unsigned int n) : nSE(n) {}
~SE_Exception() {}
unsigned int getSeNumber() { return nSE; }
};
void SEFunc() {
__try {
int x, y = 0;
x = 5 / y;
}
__finally {
printf_s( "In finally\n" );
}
}
void trans_func( unsigned int u, _EXCEPTION_POINTERS* pExp ) {
printf_s( "In trans_func.\n" );
throw SE_Exception( u );
}
int main() {
_set_se_translator( trans_func );
try {
SEFunc();
}
catch( SE_Exception e ) {
printf_s( "Caught a __try exception with SE_Exception.\n" );
printf_s( "nSE = 0x%x\n", e.getSeNumber() );
}
}
In trans_func.
In finally
Caught a __try exception with SE_Exception.
nSE = 0xc0000094
Ayrıca bkz.
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin