2013-03-30 1 views
2

std :: exception.what() 및 파생 클래스에서 반환하는 C 문자열의 내용은 구현에 따라 정의되지만 clang, gcc 및 Visual Studio는 예외 클래스의 이름을 나타내는 C 문자열을 반환합니다. 나는 그 소리 3.2, GCC 4.7 및 Visual Studio 2012에서 다음 코드를 실행하면 그러나 나는 이상한 결과를 얻을 : 그 소리와std :: exception.what()는 clang 및 gcc에서 예기치 않은 값을 반환하지만 VS11에서는 그렇지 않습니다.

#include <iostream> 
#include <exception> 

int main(int argc, const char * argv[]) 
{ 
    try { 
     throw std::bad_alloc(); 
    } catch (std::exception e) { 
     std::cout << e.what() << std::endl; 
    } 

    try { 
     throw std::bad_alloc(); 
    } catch (std::bad_alloc e) { 
     std::cout << e.what() << std::endl; 
    } 

    return 0; 
} 

및 출력이 출력

입니다 VS11와

std::exception 
std::bad_alloc 

이다 gcc를

bad allocation 
bad allocation 

나의 이해는 그 소리와 GCC 구현 예외 : 그래서

같은 것을() 뭔가

이며 모든 파생 클래스는이 구현을 what() 메서드로 사용합니다. I 위의 코드에서 유형 ID (E) .name을()으로 e.what() 대체한다면 '연타 및 GCC 출력

St9exception 
St9bad_alloc 

및 VS11 출력

class std::exception 
class std::bad_alloc 

I가 돈 typeid가 두 catch 블록 모두에 대해 std :: bad_alloc이 아닌 이유를 이해해야합니다. 이 동작은 what() 메서드가 잘못된 값을 반환하도록합니다. Microsoft는 std :: exception에서 파생 된 모든 클래스에 대해 what()을 다르게 구현해야합니다. 따라서 VS11에서는이 문제가 발생하지 않습니다.

+3

참조로 예외를 잡으려고하십시오. – soon

+0

그걸 고쳐서 질문에 답해줍니다. 값으로 예외를 잡아 내서 무의식적으로 std :: bad_alloc을 std :: exception으로 변환하고 bad_allocness를 잃게했습니다. 흥미로운 점은 VS11은 두 경우 모두 "불량 할당"을 반환 할 수있었습니다. 어쨌든, 당신이 질문에 대답한다면 나는 그것을 받아 들일 것입니다. – MtnViewJohn

+3

보고있는 현상을 "개체 조각"이라고합니다. –

답변

3

첫 번째 경우 새 std::exception 개체를 만들고 두 번째 - 새 std::bad_alloc 개체를 만들기 때문에이 출력이 표시됩니다. 대신에 참조로 예외를 잡아야합니다. 다음 코드는 차이를 보여 주어야한다 :

#include <iostream> 
#include <string> 

class Foo 
{ 
public: 
    Foo() 
    { 
     // std::cout << "Foo()" << std::endl; 
    } 

    Foo(const Foo&) 
    { 
     std::cout << "Foo(const Foo&)" << std::endl; 
    } 

    virtual ~Foo() 
    { 

    } 

    virtual std::string what() const 
    { 
     return "what: Foo"; 
    } 
}; 

class Bar: public Foo 
{ 
public: 
    Bar() 
    { 
     // std::cout << "Bar()" << std::endl; 
    } 

    Bar(const Bar&) 
    { 
     std::cout << "Bar(const Bar&)" << std::endl; 
    } 

    std::string what() const 
    { 
     return "what: Bar"; 
    } 
}; 

int main() 
{ 
    try 
    { 
     throw Bar(); 
    } 
    catch(Foo f) 
    { 
     std::cout << f.what() << std::endl; 
    } 

    try 
    { 
     throw Bar(); 
    } 
    catch(const Foo& f) 
    { 
     std::cout << f.what() << std::endl; 
    } 

    return 0; 
} 

출력은

Foo(const Foo&) 
what: Foo 
what: Bar 

입니다하지만 VS11이없는, 그래서 VS이 같은 출력을 생성 왜 나는 당신을 말할 수 없다. 누군가가 이것을 분명히한다면 그것은 좋을 것입니다. @BoPersson에

감사 :

VC++ 예외의 기본 클래스에 메시지 텍스트를 저장하여 무엇을() 를 구현하기 때문에 영업 이익의 경우 서로 다른 메시지입니다. 다른 구현은 그렇지 않습니다.

+3

OP의 경우와 다른 메시지는 VC++가'exception' 기본 클래스에 메시지 텍스트를 저장함으로써'what()'을 구현하기 때문입니다. 다른 구현에서는 그렇지 않습니다. –

관련 문제