8.9(목) C++ - 예외이야기

from Study/C++ 2007/08/12 21:19 view 23071

#include <iostream>

using namespace std;

 

// 예외이야기- 진짜 예외는 객체를(클래스) 만들어서 계층화 해야 한다.

// 예상치 않은 에러가 난다면 설계가 잘못된 것.(사용자가 지정하지 않은 에러)

// 롤백- 예외 발생시 다시 안전된 상태로 돌려놔야 한다.

 

class Exception {};

class StackException : public Exception {};

class StackUnderflowException : public StackException {};

 

// 예외 안전성의 개념

// 1. 기본보장: 예외 처리후 메모리등의 리소스낭비는 없지만 프로그램의 상태를 알
                        수는 없다
.

// 2. 강력보장: 예외를 처리한 후 프로그램의 상태가 예외발생 이전으로 복구된다.

// 3. 완전보장: 예외가없다. int a = 10;

 

// 예외중립( Exception neutral )

// exceptional c++
http://cafe.naver.com/cppmaster/1516


class
Test

{

       int buf[100];

public:

       Test() { throw 1; }

};

 

void main()

{

       try

       {

       Test* p = new Test; // 1. 메모리할당

                           // 2. 생성자호출- 그런데예외가나왔다.

       // (1)에서 할당한 메모리는 해지되었을까?? 낭비인가??

       // new 자체에서 에러 발생시 낭비를 방지하는 코드가 있다.

       }

       catch( int )

       {

       }

}

 

void foo() // 어떠한 예외라도 나올 수 있다. 예외가 없다는 throw()를 붙여줘야 한다.

{

       try

       {

             char* p = new char;

       }

       catch( std::bad_alloc e )

       {

             // 어떻게 처리할까?

             // 1. 메모리를 재할당해서 성공할 수 있다면 ok.

             // 2. 그렇지 않다면 호출자에게 다시 전달.. - 예외중립

             throw;

       }

}

 

//////////////////////////////////////////////////////////////////

// 아래 대입 연산자가 예외안전성을 지원하는가?

class String

{

       char* buff;

       int sz;

public:

 

       String& operator=( const String& s )

       {

             if ( &s == this ) return *this;

            

             char* temp = new char[ s.sz+1 ]; // 예외가 발생 할 수도 있다.

 

             strcpy( buff, s.buff );

 

             // 예외가 발생하지 않는 코드(강력보장)는 나중에 수행하자.

             delete[] buff;      // 예외가 없다.

             buff = temp;

             sz = s.sz;          // 예외가 없다.

 

             return *this;

       }

};

 

void main()

{

       String s1 = "hello";

       String s2 = "A";

 

       try

       {

             s1 = s2;

       }

       catch ( ... )

       {

       }

 

       cout << s1 << endl;   // 'A' 또는'hello" 가나와야한다.

}

 

class Stack

{

       int buf[10];

       int top;

public:

 

       int Pop() throw( StackUnderflowException )

       {

             if ( top < 0 )

             {

                    throw StackUnderflowException();

             }

             return buf[--top];

       }

};

 

void main()

{

       Stack s;

       try

       {

             int n = s.Pop();

       }

       catch( StackUnderflowException e )

       {

             cout << "예외처리" << endl;

       }

       // 예외를 잡아서 문제를 처리했다. 이제 stack을 계속 사용할 수 있을까?

       s.Push(10);

}

 

Tag |

Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다