Aracılığıyla paylaş


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_Exceptiontü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.

C (Yapılandırılmış) ve C++ özel durumlarını karıştırma