Przetwarzanie wyjątków

Po wykonaniu programu może wystąpić wiele nietypowych warunków i błędów nazywanych "wyjątkami". Mogą to obejmować brak pamięci, błędy alokacji zasobów i błędy znajdowania plików.

Biblioteka klas programu Microsoft Foundation używa schematu obsługi wyjątków, który jest modelowany ściśle po tym, który został zaproponowany przez komitet standardów ANSI dla języka C++. Przed wywołaniem funkcji, która może napotkać nietypową sytuację, należy skonfigurować procedurę obsługi wyjątków. Jeśli funkcja napotka nieprawidłowy warunek, zgłasza wyjątek i kontrolkę jest przekazywana do procedury obsługi wyjątków.

Kilka makr dołączonych do biblioteki klas programu Microsoft Foundation skonfiguruje programy obsługi wyjątków. W razie potrzeby wiele innych funkcji globalnych ułatwia zgłaszanie wyspecjalizowanych wyjątków i kończenie programów. Te makra i funkcje globalne należą do następujących kategorii:

  • Makra wyjątków, które strukturyją program obsługi wyjątków.

  • Funkcje zgłaszania wyjątków), które generują wyjątki określonych typów.

  • Funkcje kończenia, które powodują zakończenie programu.

Aby uzyskać przykłady i więcej szczegółów, zobacz artykuł Wyjątki.

Makra wyjątków

Nazwa/nazwisko opis
SPRÓBUJ Wyznacza blok kodu do przetwarzania wyjątków.
ZŁAPAĆ Wyznacza blok kodu do przechwytywania wyjątku z poprzedniego bloku TRY .
CATCH_ALL Wyznacza blok kodu do przechwytywania wszystkich wyjątków z poprzedniego bloku TRY .
AND_CATCH Wyznacza blok kodu do przechwytywania dodatkowych typów wyjątków z poprzedniego bloku TRY .
AND_CATCH_ALL Wyznacza blok kodu do przechwytywania wszystkich innych dodatkowych typów wyjątków zgłoszonych w poprzednim bloku TRY .
END_CATCH Kończy ostatni blok kodu CATCH lub AND_CATCH .
END_CATCH_ALL Kończy ostatni blok kodu CATCH_ALL .
RZUCAĆ Zgłasza określony wyjątek.
THROW_LAST Zgłasza obecnie obsługiwany wyjątek do następnego programu obsługi zewnętrznej.

Funkcje zgłaszania wyjątków

Nazwa/nazwisko opis
AfxThrowArchiveException Zgłasza wyjątek archiwum.
AfxThrowFileException Zgłasza wyjątek pliku.
AfxThrowInvalidArgException Zgłasza nieprawidłowy wyjątek argumentu.
AfxThrowMemoryException Zgłasza wyjątek pamięci.
AfxThrowNotSupportedException Zgłasza wyjątek nieobsługiwany.
AfxThrowResourceException Zgłasza wyjątek nieznaleziony zasób systemu Windows.
AfxThrowUserException Zgłasza wyjątek w akcji programu zainicjowanej przez użytkownika.

MFC udostępnia dwie funkcje zgłaszania wyjątków specjalnie dla wyjątków OLE:

Funkcje wyjątków OLE

Nazwa/nazwisko opis
AfxThrowOleDispatchException Zgłasza wyjątek w funkcji automatyzacji OLE.
AfxThrowOleException Zgłasza wyjątek OLE.

Aby obsługiwać wyjątki bazy danych, klasy baz danych udostępniają dwie klasy wyjątków oraz CDBExceptionCDaoExceptionfunkcje globalne do obsługi typów wyjątków:

Funkcje wyjątków DAO

Nazwa/nazwisko opis
AfxThrowDAOException Zgłasza wyjątek CDaoException z własnego kodu.
AfxThrowDBException Zgłasza wyjątek CDBException z własnego kodu.

MFC udostępnia następującą funkcję kończenia:

Funkcje kończenia

Nazwa/nazwisko opis
AfxAbort Wywoływana w celu przerwania działania aplikacji w przypadku wystąpienia błędu krytycznego.

TRY

Konfiguruje blok TRY .

TRY

Uwagi

Blok TRY identyfikuje blok kodu, który może zgłaszać wyjątki. Te wyjątki są obsługiwane w następujących blokach CATCH i AND_CATCH . Rekursja jest dozwolona: wyjątki mogą być przekazywane do zewnętrznego bloku TRY , ignorując je lub używając makra THROW_LAST. Zakończ blok TRY przy użyciu makra END_CATCH lub END_CATCH_ALL.

Aby uzyskać więcej informacji, zobacz artykuł Wyjątki.

Przykład

Zobacz przykład catch.

Wymagania

Nagłówek: afx.h

ZŁAPAĆ

Definiuje blok kodu, który przechwytuje pierwszy typ wyjątku zgłoszony w poprzednim bloku TRY .

CATCH(exception_class, exception_object_pointer_name)

Parametry

exception_class
Określa typ wyjątku do przetestowania. Aby uzyskać listę standardowych klas wyjątków, zobacz klasa CException.

exception_object_pointer_name
Określa nazwę wskaźnika obiektu wyjątku, który zostanie utworzony przez makro. Możesz użyć nazwy wskaźnika, aby uzyskać dostęp do obiektu wyjątku w bloku CATCH . Ta zmienna jest zadeklarowana dla Ciebie.

Uwagi

Kod przetwarzania wyjątków może przesłuchiwali obiekt wyjątku, jeśli jest to konieczne, aby uzyskać więcej informacji na temat konkretnej przyczyny wyjątku. Wywołaj makro THROW_LAST, aby przenieść przetwarzanie do następnej zewnętrznej ramki wyjątku. Zakończ blok TRY przy użyciu makra END_CATCH.

Jeśli exception_class jest klasą CException, wszystkie typy wyjątków zostaną przechwycone. Możesz użyć funkcji składowej CObject::IsKindOf , aby określić, który wyjątek został zgłoszony. Lepszym sposobem na przechwycenie kilku rodzajów wyjątków jest użycie sekwencyjnych instrukcji AND_CATCH , z których każdy ma inny typ wyjątku.

Wskaźnik obiektu wyjątku jest tworzony przez makro. Nie musisz deklarować go samodzielnie.

Uwaga

Blok CATCH jest definiowany jako zakres C++ oddzielony nawiasami klamrowymi. W przypadku deklarowania zmiennych w tym zakresie są one dostępne tylko w tym zakresie. Dotyczy to również exception_object_pointer_name.

Aby uzyskać więcej informacji na temat wyjątków i makra CATCH, zobacz artykuł Wyjątki.

Przykład

CFile* pFile = NULL;
// Constructing a CFile object with this override may throw
// a CFile exception and won't throw any other exceptions.
// Calling CString::Format() may throw a CMemoryException,
// so we have a catch block for such exceptions, too. Any
// other exception types this function throws will be
// routed to the calling function.
TRY
{
   pFile = new CFile(_T("C:\\WINDOWS\\SYSTEM.INI"),
      CFile::modeRead | CFile::shareDenyNone);
   ULONGLONG dwLength = pFile->GetLength();
   CString str;
   str.Format(_T("Your SYSTEM.INI file is %I64u bytes long.") , dwLength);
   AfxMessageBox(str);
}
CATCH(CFileException, pEx)
{
   // Simply show an error message to the user.
   pEx->ReportError();
}
AND_CATCH(CMemoryException, pEx)
{
   // We can't recover from this memory exception, so we'll
   // just terminate the app without any cleanup. Normally, 
   // an application should do everything it possibly can to
   // clean up properly and not call AfxAbort().
   AfxAbort();
}
END_CATCH
// If an exception occurs in the CFile constructor,
// the language will free the memory allocated by new
// and will not complete the assignment to pFile.
// Thus, our cleanup code needs to test for NULL.
if (pFile != NULL)
{
   pFile->Close();
   delete pFile;
}

CATCH_ALL

Definiuje blok kodu, który przechwytuje wszystkie typy wyjątków zgłoszonych w poprzednim bloku TRY .

CATCH_ALL(exception_object_pointer_name)

Parametry

exception_object_pointer_name
Określa nazwę wskaźnika obiektu wyjątku, który zostanie utworzony przez makro. Możesz użyć nazwy wskaźnika, aby uzyskać dostęp do obiektu wyjątku CATCH_ALL w bloku. Ta zmienna jest zadeklarowana dla Ciebie.

Uwagi

Kod przetwarzania wyjątków może przesłuchiwali obiekt wyjątku, jeśli jest to konieczne, aby uzyskać więcej informacji na temat konkretnej przyczyny wyjątku. Wywołaj makro, THROW_LAST aby przenieść przetwarzanie do następnej zewnętrznej ramki wyjątku. Jeśli używasz CATCH_ALL, zakończ blok TRY przy użyciu makra END_CATCH_ALL.

Uwaga

Blok CATCH_ALL jest definiowany jako zakres C++ oddzielony nawiasami klamrowymi. W przypadku deklarowania zmiennych w tym zakresie są one dostępne tylko w tym zakresie.

Aby uzyskać więcej informacji na temat wyjątków, zobacz artykuł Wyjątki.

Przykład

Zobacz przykład dla pliku CFile::Abort.

Wymagania

Nagłówek afx.h

AND_CATCH

Definiuje blok kodu do przechwytywania dodatkowych typów wyjątków zgłoszonych w poprzednim bloku TRY .

AND_CATCH(exception_class, exception_object_pointer_name)

Parametry

exception_class
Określa typ wyjątku do przetestowania. Aby uzyskać listę standardowych klas wyjątków, zobacz klasa CException.

exception_object_pointer_name
Nazwa wskaźnika obiektu wyjątku, który zostanie utworzony przez makro. Możesz użyć nazwy wskaźnika, aby uzyskać dostęp do obiektu wyjątku w bloku AND_CATCH . Ta zmienna jest zadeklarowana dla Ciebie.

Uwagi

Użyj makra CATCH, aby przechwycić jeden typ wyjątku, a następnie makro AND_CATCH, aby przechwycić każdy kolejny typ. Zakończ blok TRY przy użyciu makra END_CATCH.

Kod przetwarzania wyjątków może przesłuchiwali obiekt wyjątku, jeśli jest to konieczne, aby uzyskać więcej informacji na temat konkretnej przyczyny wyjątku. Wywołaj makro THROW_LAST w bloku AND_CATCH , aby przenieść przetwarzanie do następnej zewnętrznej ramki wyjątku. AND_CATCH oznacza koniec poprzedniego bloku CATCH lub AND_CATCH.

Uwaga

Blok AND_CATCH jest definiowany jako zakres języka C++ (oddzielony nawiasami klamrowymi). Jeśli zadeklarujesz zmienne w tym zakresie, pamiętaj, że są one dostępne tylko w tym zakresie. Dotyczy to również zmiennej exception_object_pointer_name .

Przykład

Zobacz przykład catch.

Wymagania

Nagłówek afx.h

AND_CATCH_ALL

Definiuje blok kodu do przechwytywania dodatkowych typów wyjątków zgłoszonych w poprzednim bloku TRY .

AND_CATCH_ALL(exception_object_pointer_name)

Parametry

exception_object_pointer_name
Nazwa wskaźnika obiektu wyjątku, który zostanie utworzony przez makro. Możesz użyć nazwy wskaźnika, aby uzyskać dostęp do obiektu wyjątku w bloku AND_CATCH_ALL . Ta zmienna jest zadeklarowana dla Ciebie.

Uwagi

Użyj makra CATCH , aby przechwycić jeden typ wyjątku, a następnie makro AND_CATCH_ALL, aby przechwycić wszystkie inne kolejne typy. Jeśli używasz AND_CATCH_ALL, zakończ blok TRY przy użyciu makra END_CATCH_ALL.

Kod przetwarzania wyjątków może przesłuchiwali obiekt wyjątku, jeśli jest to konieczne, aby uzyskać więcej informacji na temat konkretnej przyczyny wyjątku. Wywołaj makro THROW_LAST w bloku AND_CATCH_ALL , aby przenieść przetwarzanie do następnej zewnętrznej ramki wyjątku. AND_CATCH_ALL oznacza koniec poprzedniego bloku CATCH lub AND_CATCH_ALL.

Uwaga

Blok AND_CATCH_ALL jest definiowany jako zakres języka C++ (oddzielony nawiasami klamrowymi). Jeśli zadeklarujesz zmienne w tym zakresie, pamiętaj, że są one dostępne tylko w tym zakresie.

Wymagania

Nagłówek afx.h

END_CATCH

Oznacza koniec ostatniego bloku CATCH lub AND_CATCH .

END_CATCH

Uwagi

Aby uzyskać więcej informacji na temat makra END_CATCH, zobacz artykuł Wyjątki.

Wymagania

Nagłówek afx.h

END_CATCH_ALL

Oznacza koniec ostatniego bloku CATCH_ALL88 lub AND_CATCH_ALL .

END_CATCH_ALL

Wymagania

Nagłówek afx.h

THROW (MFC)

Zgłasza określony wyjątek.

THROW(exception_object_pointer)

Parametry

exception_object_pointer
Wskazuje obiekt wyjątku pochodzący z CExceptionelementu .

Uwagi

THROW przerywa wykonywanie programu, przekazując kontrolę do skojarzonego bloku CATCH w programie. Jeśli blok CATCH nie został podany, kontrolka jest przekazywana do modułu Biblioteki klas programu Microsoft Foundation, który wyświetla komunikat o błędzie i kończy działanie.

Aby uzyskać więcej informacji, zobacz artykuł Wyjątki.

Wymagania

Nagłówek afx.h

THROW_LAST

Zgłasza wyjątek z powrotem do następnego zewnętrznego bloku CATCH .

THROW_LAST()

Uwagi

To makro umożliwia zgłaszanie lokalnie utworzonego wyjątku. Jeśli spróbujesz zgłosić wyjątek, który został właśnie przechwycony, zwykle wykracza poza zakres i zostanie usunięty. W przypadku THROW_LAST wyjątek jest przekazywany poprawnie do następnej procedury obsługi CATCH .

Aby uzyskać więcej informacji, zobacz artykuł Wyjątki.

Przykład

Zobacz przykład dla pliku CFile::Abort.

Wymagania

Nagłówek afx.h

AfxThrowArchiveException

Zgłasza wyjątek archiwum.

void  AfxThrowArchiveException(int cause, LPCTSTR lpszArchiveName);

Parametry

przyczyna
Określa liczbę całkowitą, która wskazuje przyczynę wyjątku. Aby uzyskać listę możliwych wartości, zobacz CArchiveException::m_cause.

lpszArchiveName
Wskazuje ciąg zawierający nazwę CArchive obiektu, który spowodował wyjątek (jeśli jest dostępny).

Wymagania

Nagłówek afx.h

AfxThrowFileException

Zgłasza wyjątek pliku.

void AfxThrowFileException(
    int cause,
    LONG lOsError = -1,
    LPCTSTR lpszFileName = NULL);

Parametry

przyczyna
Określa liczbę całkowitą, która wskazuje przyczynę wyjątku. Aby uzyskać listę możliwych wartości, zobacz CFileException::m_cause.

lOsError
Zawiera numer błędu systemu operacyjnego (jeśli jest dostępny), który wskazuje przyczynę wyjątku. Zapoznaj się z podręcznikiem systemu operacyjnego, aby zapoznać się z listą kodów błędów.

lpszFileName
Wskazuje ciąg zawierający nazwę pliku, który spowodował wyjątek (jeśli jest dostępny).

Uwagi

Odpowiadasz za określenie przyczyny na podstawie kodu błędu systemu operacyjnego.

Wymagania

Nagłówek afx.h

AfxThrowInvalidArgException

Zgłasza nieprawidłowy wyjątek argumentu.

Składnia

void AfxThrowInvalidArgException( );

Uwagi

Ta funkcja jest wywoływana, gdy są używane nieprawidłowe argumenty.

Wymagania

Nagłówek: afx.h

AfxThrowMemoryException

Zgłasza wyjątek pamięci.

void AfxThrowMemoryException();

Uwagi

Wywołaj tę funkcję, jeśli wywołania do podstawowych alokatorów pamięci systemu (takich jak malloc i funkcja GlobalAlloc systemu Windows) kończą się niepowodzeniem. Nie trzeba go new wywoływać, ponieważ new zgłosi wyjątek pamięci automatycznie, jeśli alokacja pamięci zakończy się niepowodzeniem.

Wymagania

Nagłówek afx.h

AfxThrowNotSupportedException

Zgłasza wyjątek, który jest wynikiem żądania dla nieobsługiwanej funkcji.

void AfxThrowNotSupportedException();

Wymagania

Nagłówek afx.h

AfxThrowResourceException

Zgłasza wyjątek zasobu.

void  AfxThrowResourceException();

Uwagi

Ta funkcja jest zwykle wywoływana, gdy nie można załadować zasobu systemu Windows.

Wymagania

Nagłówek afx.h

AfxThrowUserException

Zgłasza wyjątek, aby zatrzymać operację użytkownika końcowego.

void AfxThrowUserException();

Uwagi

Ta funkcja jest zwykle wywoływana natychmiast po AfxMessageBox zgłoszeniu błędu użytkownikowi.

Wymagania

Nagłówek afx.h

AfxThrowOleDispatchException

Użyj tej funkcji, aby zgłosić wyjątek w funkcji automatyzacji OLE.

void AFXAPI AfxThrowOleDispatchException(
    WORD wCode ,
    LPCSTR lpszDescription,
    UINT nHelpID = 0);

void AFXAPI AfxThrowOleDispatchException(
    WORD wCode,
    UINT nDescriptionID,
    UINT nHelpID = -1);

Parametry

Kod wCode
Kod błędu specyficzny dla aplikacji.

lpszDescription
Słowny opis błędu.

nDescriptionID
Identyfikator zasobu dla opisu błędu słownego.

nHelpID
Kontekst pomocy dla pomocy aplikacji (. Plik HLP).

Uwagi

Informacje podane w tej funkcji mogą być wyświetlane przez aplikację napędową (Microsoft Visual Basic lub inną aplikację kliencą automatyzacji OLE).

Przykład

// Sort is method of automation class CStrArrayDoc
long CStrArrayDoc::Sort(VARIANT* vArray)
{
   USES_CONVERSION;

   // Type check VARIANT parameter. It should contain a BSTR array
   // passed by reference. The array must be passed by reference; it is
   // an in-out-parameter.

   // throwing COleDispatchException allows the EXCEPINFO structure of 
   // IDispatch::Invoke() to set
   if (V_VT(vArray) != (VT_ARRAY | VT_BSTR))
      AfxThrowOleDispatchException(1001,
         _T("Type Mismatch in Parameter. Pass a string array by reference"));

   // ...
   // ...

   return 0;
}

Wymagania

Nagłówek afx.h

AfxThrowOleException

Tworzy obiekt typu COleException i zgłasza wyjątek.

void AFXAPI AfxThrowOleException(SCODE sc);
void AFXAPI AfxThrowOleException(HRESULT hr);

Parametry

Sc
Kod stanu OLE wskazujący przyczynę wyjątku.

Hr
Dojmij do kodu wynikowego, który wskazuje przyczynę wyjątku.

Uwagi

Wersja, która przyjmuje element HRESULT jako argument, konwertuje kod wynikowy na odpowiadający mu kod SCODE. Aby uzyskać więcej informacji na temat HRESULT i SCODE, zobacz Struktura kodów błędów COM w zestawie Windows SDK.

Wymagania

Nagłówek afxdao.h

AfxThrowDaoException

Wywołaj tę funkcję, aby zgłosić wyjątek typu CDaoException z własnego kodu.

void AFXAPI AfxThrowDaoException(
    int nAfxDaoError = NO_AFX_DAO_ERROR,
    SCODE scode = S_OK);

Parametry

nAfxDaoError
Wartość całkowita reprezentująca rozszerzony kod błędu daO, który może być jedną z wartości wymienionych w obszarze CDaoException::m_nAfxDaoError.

Scode
Kod błędu OLE z DAO typu SCODE. Aby uzyskać informacje, zobacz CDaoException::m_scode.

Uwagi

Platforma wywołuje również metodę AfxThrowDaoException. W wywołaniu można przekazać jeden z parametrów lub obu tych parametrów. Jeśli na przykład chcesz zgłosić jeden z błędów zdefiniowanych w CDaoException::nAfxDaoError , ale nie dbasz o parametr scode , przekaż prawidłowy kod w parametrze nAfxDaoError i zaakceptuj wartość domyślną dla kodu.

Aby uzyskać informacje o wyjątkach związanych z klasami MFC DAO, zobacz klasę CDaoException w tej książce i artykuł Wyjątki: wyjątki bazy danych.

Wymagania

Nagłówek afxdb.h

AfxThrowDBException

Wywołaj tę funkcję, aby zgłosić wyjątek typu CDBException z własnego kodu.

void AfxThrowDBException(
    RETCODE nRetCode,
    CDatabase* pdb,
    HSTMT hstmt);

Parametry

nRetCode
Wartość typu RETCODE definiująca typ błędu, który spowodował zgłoszenie wyjątku.

Pdb
Wskaźnik do CDatabase obiektu, który reprezentuje połączenie ze źródłem danych, z którym jest skojarzony wyjątek.

Hstmt
Dojście HSTMT ODBC określające uchwyt instrukcji, z którym jest skojarzony wyjątek.

Uwagi

Struktura wywołuje AfxThrowDBException kod RETCODE ODBC z wywołania funkcji interfejsu API ODBC i interpretuje kod RETCODE jako wyjątkowy warunek, a nie oczekiwany błąd. Na przykład operacja dostępu do danych może zakończyć się niepowodzeniem z powodu błędu odczytu dysku.

Aby uzyskać informacje o wartościach RETCODE zdefiniowanych przez ODBC, zobacz Rozdział 8, "Pobieranie informacji o stanie i błędzie" w zestawie WINDOWS SDK. Aby uzyskać informacje o rozszerzeniach MFC do tych kodów, zobacz klasa CDBException.

Wymagania

Nagłówek afx.h

AfxAbort

Domyślna funkcja zakończenia dostarczana przez MFC.

void  AfxAbort();

Uwagi

AfxAbort jest wywoływana wewnętrznie przez funkcje składowe MFC, gdy występuje błąd krytyczny, taki jak nieuchwycony wyjątek, którego nie można obsłużyć. Wywołanie można wywołać AfxAbort w rzadkich przypadkach, gdy wystąpi katastrofalny błąd, z którego nie można odzyskać.

Przykład

Zobacz przykład catch.

Wymagania

Nagłówek afx.h

Zobacz też

Makra i globalne
Klasa CException
Klasa CInvalidArgException