프로그래밍C++ 시스템 프로그래머

C++에서 예외(예외)의 작동 메커니즘에 대해 설명하십시오. 오류를 올바르게 처리하는 방법과 noexcept의 필요성은 무엇입니까?

Hintsage AI 어시스턴트로 면접 통과

답변.

질문 배경:

C++에서 예외 처리 메커니즘은 오류 코드를 사용하는 대신 보다 신뢰성 있고 구조화된 오류 처리를 제공하기 위해 도입되었습니다. 시간이 지남에 따라 구문이 확장되었으며, 함수에서 예외가 발생하지 않도록 제어하기 위한 noexcept와 같은 형식 지정자가 추가되었습니다.

문제점:

예외를 잘못 처리하면 종종 메모리 누수, 정의되지 않은 동작 또는 애플리케이션 충돌로 이어집니다. 생성자나 소멸자에서, 또는 리소스 작업 중에 예외를 던지는 것을 고려하지 않으면 프로그램의 상태에 심각한 문제가 발생합니다.

해결책:

기본 구문은 try-catch 사용입니다. 예외는 모든 유형이 될 수 있지만, 사용자 정의 예외는 std::exception에서 상속하는 것이 좋습니다. noexcept 키워드(C++11+)는 함수가 예외를 던지지 않아야 함을 나타내며, noexcept 함수에서 예외가 던져지면 std::terminate()를 호출합니다.

코드 예:

#include <iostream> #include <stdexcept> void func() noexcept(false) { throw std::runtime_error("Error!"); } int main() { try { func(); } catch(const std::exception& ex) { std::cout << ex.what(); } }

주요 특징:

  • 예외는 자동 unwind(스택 펼치기)를 보장합니다.
  • noexcept는 함수가 확실히 예외를 던지지 않을 때 컴파일러가 최적화할 수 있게 합니다.
  • 오직 std::exception 및 그 파생 클래스만이 what() 메서드의 존재를 보장합니다.

속임수 질문.

소멸자에서 예외를 던지는 것이 허용됩니까?

아니요, 소멸자에서 예외를 던지면 스택이 펼쳐지는 동안 std::terminate()로 이어집니다. 소멸자 안에서 예외를 잡아야 합니다.

noexcept 함수에서 예외를 던지면 어떻게 됩니까?

std::terminate가 호출되고, 프로그램이 강제로 종료됩니다. noexcept는 엄격한 계약입니다.

값에 따라 예외를 잡을 수 있습니까? 이것이 위험한 이유는 무엇입니까?

값에 따라 잡는 것은 가능하지만 객체가 복사됩니다(객체 슬라이싱). const &를 사용하는 것이 좋습니다.

코드 예:

try { throw std::out_of_range("err"); } catch (const std::exception& e) { /* ... */ }

전형적인 오류 및 안티패턴

  • 소멸자에서 throw 사용
  • 로그 없이 catch(...)로 예외를 숨김
  • 가능한 곳에서 noexcept 미지정

실생활 예시

부정적인 사례

코드가 리소스의 소멸자에서 예외를 던졌습니다. 비정상 종료 시 스택이 올바르게 펼쳐지지 않아 리소스가 누수되었습니다.

장점:

  • 오류를 빠르게 발견할 수 있음

단점:

  • 프로그램이 자주 terminate 오류로 종료됨

긍정적인 사례

중요한 메서드에 noexcept를 표시하고 소멸자가 모든 예외를 내부에서 처리했습니다. 참조에 대한 catch를 사용하고 모든 오류를 로깅했습니다.

장점:

  • 신뢰성, 누수 없음
  • 매우 예측 가능한 동작

단점:

  • 올바르고 "깨끗한" 코드를 작성할 때 개발자에게 더 높은 엄격성 요구