logo

C++의 예외 처리

C++에서 예외는 프로그램이 실행되는 동안 발생하는 런타임 이상 또는 비정상적인 조건입니다. 이러한 예외를 처리하는 프로세스를 예외 처리라고 합니다. 예외 처리 메커니즘을 사용하면 예외가 발생한 프로그램 부분의 제어를 코드의 다른 부분으로 전송할 수 있습니다.

따라서 기본적으로 C++의 예외 처리를 사용하면 프로그램이 계속 실행되도록 예외를 처리할 수 있습니다.



객체 자바 란 무엇입니까?

C++ 예외란 무엇입니까?

예외는 프로그램 실행 중에 발생하는 예상치 못한 문제로, 일부 오류/문제로 인해 프로그램이 갑자기 종료됩니다. 프로그램 실행(런타임) 중에 예외가 발생합니다.

C++ 예외 유형

C++에는 두 가지 유형의 예외가 있습니다.

  1. 동기식: 입력 데이터의 실수로 인해 문제가 발생하거나 숫자를 0으로 나누는 등 프로그램이 현재 작업 중인 데이터 유형을 처리할 수 있는 장비를 갖추고 있지 않은 경우 발생하는 예외입니다.
  2. 비동기식 : 디스크 장애, 키보드 인터럽트 등 프로그램의 통제를 벗어난 예외 사항입니다.

C++ 시도하고 잡아라

C++에서는 예외 처리를 위한 내장 기능을 제공합니다. 이는 다음과 같은 특수 키워드를 사용하여 수행할 수 있습니다: try, catch 및 throw 각각은 서로 다른 목적을 가지고 있습니다.



C++의 try-catch 구문

  try   {     // Code that might throw an exception          throw   SomeExceptionType('Error message');  }    catch  ( ExceptionName e1 ) {     // catch block catches the exception that is thrown from try block   }>

1. C++로 시도해 보세요

try 키워드는 try 블록 내에 있는 예외를 발생시킬 수 있는 코드 블록을 나타냅니다. 그 뒤에는 하나 이상의 catch 블록이 옵니다. 예외가 발생하면 try 블록이 해당 예외를 발생시킵니다.

2. C++로 잡기

catch 문은 try 블록에서 특정 예외가 발생할 때 실행되는 코드 블록을 나타냅니다. 예외를 처리하는 코드는 catch 블록 내부에 작성됩니다.

3. C++를 던져라

C++에서는 throw 키워드를 사용하여 예외가 발생될 수 있습니다. 프로그램이 throw 문을 만나면 즉시 현재 함수를 종료하고 throw된 예외를 처리하기 위해 일치하는 catch 블록을 찾기 시작합니다.



메모: 여러 catch 문을 사용하여 try 블록에서 발생하는 다양한 유형의 예외를 잡을 수 있습니다.

try 및 catch 키워드는 쌍으로 제공됩니다. try 블록을 사용하여 일부 코드를 테스트하고 코드에서 예외가 발생하면 catch 블록에서 이를 처리합니다.

왜 우리에게 필요합니까? C++의 예외 처리?

다음은 기존 오류 처리에 비해 예외 처리의 주요 장점입니다.

  1. 오류 처리 코드와 일반 코드의 분리 : 기존 오류 처리 코드에는 오류를 처리하기 위한 if-else 조건이 항상 있습니다. 이러한 조건과 오류를 처리하는 코드는 일반적인 흐름과 혼동됩니다. 이로 인해 코드 읽기 및 유지 관리가 어려워집니다. try/catch 블록을 사용하면 오류 처리 코드가 일반 흐름과 분리됩니다.
  2. 함수/메소드는 자신이 선택한 예외만 처리할 수 있습니다. : 함수는 많은 예외를 발생시킬 수 있지만 그 중 일부를 처리하도록 선택할 수도 있습니다. 발생했지만 포착되지 않은 다른 예외는 호출자가 처리할 수 있습니다. 호출자가 이를 포착하지 않기로 선택한 경우 호출자의 호출자가 예외를 처리합니다.
    C++에서 함수는 throw 키워드를 사용하여 발생하는 예외를 지정할 수 있습니다. 이 함수의 호출자는 예외를 어떤 방식으로든 처리해야 합니다(다시 지정하거나 포착하여).
  3. 오류 유형 그룹화 : C++에서는 기본 유형과 객체 모두 예외로 발생할 수 있습니다. 예외 객체의 계층 구조를 만들고, 네임스페이스나 클래스에서 예외를 그룹화하고, 유형에 따라 분류할 수 있습니다.

C++의 예외 처리 예

다음 예제에서는 try-catch 블록을 사용하여 C++에서 예외를 처리하는 방법을 보여줍니다.

실시예 1

아래 예제에서는 C++에서 예외 발생을 보여줍니다.

C++




// C++ program to demonstate the use of try,catch and throw> // in exception handling.> #include> #include> using> namespace> std;> int> main()> {> >// try block> >try> {> >int> numerator = 10;> >int> denominator = 0;> >int> res;> >// check if denominator is 0 then throw runtime> >// error.> >if> (denominator == 0) {> >throw> runtime_error(> >'Division by zero not allowed!'>);> >}> >// calculate result if no exception occurs> >res = numerator / denominator;> >//[printing result after division> >cout <<>'Result after division: '> << res << endl;> >}> >// catch block to catch the thrown exception> >catch> (>const> exception& e) {> >// print the exception> >cout <<>'Exception '> << e.what() << endl;> >}> >return> 0;> }>

>

>

산출

Exception Division by zero not allowed!>

실시예 2

다음은 C++의 예외 처리를 보여주는 간단한 예입니다. 프로그램의 출력은 try/catch 블록의 실행 흐름을 설명합니다.

CPP




// C++ program to demonstate the use of try,catch and throw> // in exception handling.> #include> using> namespace> std;> int> main()> {> >int> x = -1;> >// Some code> >cout <<>'Before try '>;> >// try block> >try> {> >cout <<>'Inside try '>;> >if> (x <0) {> >// throwing an exception> >throw> x;> >cout <<>'After throw (Never executed) '>;> >}> >}> >// catch block> >catch> (>int> x) {> >cout <<>'Exception Caught '>;> >}> >cout <<>'After catch (Will be executed) '>;> >return> 0;> }>

>

>

산출

Before try Inside try Exception Caught After catch (Will be executed)>

C++의 예외 처리 속성

속성 1

모든 유형의 예외를 잡는 데 사용할 수 있는 catch(...)로 작성된 'catch-all' 블록이라는 특수 catch 블록이 있습니다.

이메일

다음 프로그램에서는 int가 예외로 발생하지만 int에 대한 catch 블록이 없으므로 catch(…) 블록이 실행됩니다.

CPP




// C++ program to demonstate the use of catch all> // in exception handling.> #include> using> namespace> std;> int> main()> {> >// try block> >try> {> >// throw> >throw> 10;> >}> >// catch block> >catch> (>char>* excp) {> >cout <<>'Caught '> << excp;> >}> >// catch all> >catch> (...) {> >cout <<>'Default Exception '>;> >}> >return> 0;> }>

>

>

산출

Default Exception>

속성 2

기본 유형의 경우 암시적 유형 변환이 발생하지 않습니다.

다음 프로그램에서 'a'는 암시적으로 int로 변환되지 않습니다.

CPP




//// C++ program to demonstate property 2: Implicit type> /// conversion doesn't happen for primitive types.> // in exception handling.> #include> using> namespace> std;> int> main()> {> >try> {> >throw> 'a'>;> >}> >catch> (>int> x) {> >cout <<>'Caught '> << x;> >}> >catch> (...) {> >cout <<>'Default Exception '>;> >}> >return> 0;> }>

>

>

산출

Default Exception>

산출:

Default Exception>

속성 3

예외가 발생했지만 아무데도 포착되지 않으면 프로그램이 비정상적으로 종료됩니다.

다음 프로그램에서는 char이 발생하지만 char을 잡을 catch 블록이 없습니다.

CPP




지도용 자바 반복자

// C++ program to demonstate property 3: If an exception is> // thrown and not caught anywhere, the program terminates> // abnormally in exception handling.> #include> using> namespace> std;> int> main()> {> >try> {> >throw> 'a'>;> >}> >catch> (>int> x) {> >cout <<>'Caught '>;> >}> >return> 0;> }>

>

>

산출

terminate called after throwing an instance of 'char'>

예상치 못한 함수를 작성하여 이러한 비정상적인 종료 동작을 변경할 수 있습니다.

메모 : 파생 클래스 예외는 기본 클래스 예외보다 먼저 포착되어야 합니다.

Java와 마찬가지로 C++ 라이브러리에도 표준 예외 모든 표준 예외의 기본 클래스인 클래스입니다. 표준 라이브러리의 구성 요소에 의해 생성된 모든 개체는 이 클래스에서 파생됩니다. 따라서 이 유형을 catch하면 모든 표준 예외를 catch할 수 있습니다.

속성 4

Java와 달리 C++에서는 모든 예외가 확인되지 않습니다. 즉, 컴파일러는 예외가 포착되었는지 여부를 확인하지 않습니다(참조 이것 자세한 내용은). 따라서 함수 선언에서 포착되지 않은 모든 예외를 지정할 필요는 없습니다. 그러나 예외 처리는 그렇게 하는 것이 좋습니다.

다음 프로그램은 잘 컴파일되지만 이상적으로는 fun()의 시그니처에 확인되지 않은 예외가 나열되어야 합니다.

CPP




// C++ program to demonstate property 4 in exception> // handling.> #include> using> namespace> std;> // This function signature is fine by the compiler, but not> // recommended. Ideally, the function should specify all> // uncaught exceptions and function signature should be> // 'void fun(int *ptr, int x) throw (int *, int)'> void> fun(>int>* ptr,>int> x)> {> >if> (ptr == NULL)> >throw> ptr;> >if> (x == 0)> >throw> x;> >/* Some functionality */> }> int> main()> {> >try> {> >fun(NULL, 0);> >}> >catch> (...) {> >cout <<>'Caught exception from fun()'>;> >}> >return> 0;> }>

연결을 얻다

>

>

산출

Caught exception from fun()>

위의 코드를 작성하는 더 좋은 방법은 다음과 같습니다.

CPP




// C++ program to demonstate property 4 in better way> #include> using> namespace> std;> // Here we specify the exceptions that this function> // throws.> void> fun(>int>* ptr,>int> x)>throw>(> >int>*,>int>)>// Dynamic Exception specification> {> >if> (ptr == NULL)> >throw> ptr;> >if> (x == 0)> >throw> x;> >/* Some functionality */> }> int> main()> {> >try> {> >fun(NULL, 0);> >}> >catch> (...) {> >cout <<>'Caught exception from fun()'>;> >}> >return> 0;> }>

>

>

산출

Caught exception from fun()>

메모 : 동적 예외 사양의 사용은 C++11부터 더 이상 사용되지 않습니다. 그 이유 중 하나는 프로그램이 임의로 중단될 수 있기 때문일 수 있습니다. 이는 동적 예외 사양에 언급되지 않은 다른 유형의 예외를 발생시킬 때 발생할 수 있습니다. 해당 시나리오에서는 기본적으로 abort()를 호출하는 quit()를 (간접적으로) 호출하기 때문에 프로그램이 자체적으로 중단됩니다.

속성 5

C++에서는 try/catch 블록을 중첩할 수 있습니다. 또한, throw를 사용하여 예외를 다시 발생시킬 수 있습니다. .

다음 프로그램은 try/catch 블록 중첩을 보여줍니다.

CPP




// C++ program to demonstrate try/catch blocks can be nested> // in C++> #include> using> namespace> std;> int> main()> {> >// nesting of try/catch> >try> {> >try> {> >throw> 20;> >}> >catch> (>int> n) {> >cout <<>'Handle Partially '>;> >throw>;>// Re-throwing an exception> >}> >}> >catch> (>int> n) {> >cout <<>'Handle remaining '>;> >}> >return> 0;> }>

>

>

산출

Handle Partially Handle remaining>

함수는 동일한 던지기를 사용하여 함수를 다시 던질 수도 있습니다. 통사론. 함수는 부분을 처리하고 호출자에게 나머지 부분을 처리하도록 요청할 수 있습니다.

속성 6

예외가 발생하면 둘러싸는 try 블록 내부에 생성된 모든 개체는 제어가 catch 블록으로 전송되기 전에 삭제됩니다.

40개 중 10개

다음 프로그램은 위의 속성을 보여줍니다.

CPP




// C++ program to demonstrate> #include> using> namespace> std;> // Define a class named Test> class> Test {> public>:> >// Constructor of Test> >Test() { cout <<>'Constructor of Test '> << endl; }> >// Destructor of Test> >~Test() { cout <<>'Destructor of Test '> << endl; }> };> int> main()> {> >try> {> >// Create an object of class Test> >Test t1;> >// Throw an integer exception with value 10> >throw> 10;> >}> >catch> (>int> i) {> >// Catch and handle the integer exception> >cout <<>'Caught '> << i << endl;> >}> }>

>

>

산출

Constructor of Test Destructor of Test Caught 10>

C++ 예외 처리의 한계

C++의 예외 처리에도 몇 가지 제한 사항이 있습니다.

  • 코드에 보이지 않는 여러 종료 지점이 생성되어 코드를 읽고 디버깅하기가 어려워지므로 예외로 인해 코드의 구조나 흐름이 중단될 수 있습니다.
  • 예외 처리가 제대로 수행되지 않으면 리소스 누출도 발생할 수 있습니다.
  • 안전한 예외 코드를 작성하는 방법을 배우기는 어렵습니다.
  • 예외 처리를 사용하는 방법에 대한 C++ 표준이 없으므로 예외 처리 방법에는 다양한 변형이 존재합니다.

결론

C++의 예외 처리는 문제를 효율적으로 관리하기 위해 try 및 catch 블록을 사용하여 예상치 못한 상황을 처리하는 데 사용됩니다. 이러한 예외 처리는 런타임 시 오류를 별도로 처리할 수 있으므로 프로그램의 안정성을 높이고 오류 발생 시 프로그램이 중단되거나 프로그램이 갑자기 종료되는 것을 방지하는 데도 도움이 됩니다.

관련 기사:

  • 주요 C++ 예외 처리 인터뷰 질문 및 답변
  • C++의 예외 처리에 대한 퀴즈