Publish:

태그: , ,

카테고리:


🤯 언리얼을 하기 위해 C++ 기억 되살리기 프로젝트

예외 (Exception)

C++에서도 예외를 ‘지원’하긴 하나, 익셉션 핸들링의 중요성이 떨어짐.
C++ 의 예외는 프로그래머가 만든 것, 언어 자체에서 익셉션을 던져주진 않음.
std::exception 이 최상위 부모 클래스인데, 이걸 상속받아 사용하는 것.

1. 예외 발생 사례 1 : 범위 이탈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <exception>

int main()
{
    std::string myCatName = "Coco";

    try
    {
        char ch = myCatName.at(5);          // <- 익셉션 발생
    }
    catch (const std::out_of_range& e)
    {
        // 범위 이탈 발생
        std::cerr << "out of range : " << e.what() << std:: endl;
    }
    catch (const std::exception& e)
    {
        // 위에서 캐치하지 못한 익셉션 전부 캐치
        std::cerr << "exception : " << e.what() << std::endl;
    }

    return 0;
}

그런데 굳이 익셉션으로 처리해야 하느냐?

1
2
3
4
5
6
7
8
std::string myCatName = "Coco";

const size_t INDEX = 5;
if (INDEX < myCatName.size())
{
    char ch = myCatName.at(INDEX);
    // 이렇게 if문으로 처리해도 되지요
}

2. 예외 발생 사례 2 : 0으로 나누기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int number1 = 0;
int number2 = 0;

std::cin >> number1 >> number2;

try
{
    int result = number1 / number2;             // <- 익셉션이 발생하긴 하나 C++의 예외가 아님
                                                // 운영체제가 해주는 익셉션...
                                                // '정의되어 있는 상태가 아님' 이라고 뜬다
}
catch (const std::exception& e)
{
    std::cerr << "exception: " << e.what() << std::endnl;
}

3. 예외 발생 사례 3 : NULL 개체

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Cat* myCat = nullptr;
// ...

try
{
    const char* myCatName = myCat->GetName();           // 이것도 C++의 예외가 아님;;
                                                        // 운영체제에서 NULL 개체 참조하면 위험하니까
                                                        // OS에서 인터럽트 방식으로 시그널 쏴주는 것
    std::cout << myCatName << std::endl;
}
catch (const std::exception& e)
{
    std::cerr << "exception : " << e.what() << std::endl;
}

굳이 익셉션 없이 이렇게 처리해도 되쥬.

1
2
3
4
5
Cat* myCat == new Cat(5, "Coco");
if (myCat == NULL)
{
    // ...
}

4. OS 예외, C++ 예외

  • OS 예외
    • 비동기적
    • 윈도우
      • 구조적 예외 처리 (SEH)
    • 리눅스
      • Faults, Traps, Aborts
    • 플랫폼마다 다름
    • 오버헤드 비교적 많음, 더 느림
  • std::exception
    • 동기적
    • C++STL
    • 모든 플랫폼에 공통
    • 오버헤드가 비교적 적음

5. 생성자에서 사용하는 예외

1
2
3
4
Inventory::Inventory(int count)
{
    mSlots = new int[count];
}

💡 mSlots가 NULL이라면 ? 이것에 대한 해결 방법!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 해결 방법
// Exceptions.h
#include <exception>

struct SlotNullException : public std::exception
{
    const char* what() const throw()
    {
        return "Slot is NULL";
    }
}

// Inventory.cpp
Inventory::Inventory(int slotCount)
{
    mSlots = new int[slotCount];
    if (mSlots == NULL)
    {
        throw SlotNullException();
    }
}

이슈 및 공부한 것을 기록해두는 개인 블로그 입니다. 댓글, 피드백 환영합니다 🙂

Update:

댓글남기기