2013-07-05 2 views
3

unique_ptr을 사용해도 안전합니까? 소멸자에서 cout을 사용할 때 가끔 한 번 이상 호출했습니다. - 그래서 그것은 때때로 복사를합니다. 그것은 하나의 객체에서이 복사본을 가지고가는 경우 - 데이터가 손실 될 수 있습니다 .. 예외 클래스에서 unique_ptr을 사용하는 것이 안전합니까?

#include <memory> 

class MyException 
{ 
    std::unique_ptr<Type> data; 

    MyException(); 
    ~MyException() {cout<<"test"<<endl;} 

    MyException(MyException ex&); 
}; 

int main() 
{ 
    try 
    { 
     try 
     { 
      throw MyException(); 
     } 
     catch (const MyException& ex) 
     { 
      throw; 
      //or? 
      throw ex; //will be copied? 
     } 
    return 0; 
    } 
    catch(const MyException/*& will be missed. will ex be copied?*/ ex) 
    { 
     throw; //wich ex will be re-throw, copy or original? 
     //or? 
     throw ex; //will be copied? 
    } 
} 

내가 확신 할 수 있습니다, 데이터를 재 - 발생 사이에 손실되지 않습니다? 그리고 다른 레벨에서 오류 정보를 수집하기 위해 ptr을 예외적으로 사용하는 것이 좋습니다. 당신이 발견 한 것처럼 당신이 예외를 다시 던질 할 때

std::exception_ptr ex = std::current_exception(); 
std::rethrow_exception(ex); 
+1

재발행은 사본을 만들지 않습니다. 그건 보장이야. 그러나 복사본이 만들어 졌는지 여부가 명시되지 않은 다른 지점이있을 수 있습니다. –

+0

vs 2012. "throw;" - 1 "테스트"출력. "throw ex;" - 출력에서 ​​2 "테스트". 2 destructor = 2 object ... => 사본이 작성되었습니다. – Darida

답변

1

, 당신은 항상, throw;을하지하지 throw ex; 말을해야합니다 후 또한

가 손실 될 MyException.data 수 있습니다. 실제로 throw ex;은 복사하고 ( ex이 기본 클래스에 대한 참조 인 경우 슬라이스합니다.)

그래서 항상 참조로 catch하고 항상 예외의 이름을 지정하지 않고 다시 throw하십시오.

0

gcc 4.7.3을 사용하면 예제가 컴파일되지 않고 MyException의 누락 된 복사본 생성자에 대해 불평합니다. 이것은 처음 던져진 행에 있으므로 throw MyException() 자체가 이미 (적어도 gcc에서는) 복사본을 만들고 싶어합니다. this stackoverflow questionC++ FAQ을 참조하십시오.

예외 상황에서 포인터를 사용하는 것이 좋은 습관인지 여부에 대한 질문에 대답하려면 일반적으로 아니오라고 대답합니다. 예외에 피기 백되는 데이터가 크지 않으면 (설계 문제 일 가능성이 있음) 스택에 할당 된 데이터 구조를 선호해야합니다. 어쨌든 예외 처리 중에 성능이 주요 관심사가되어서는 안됩니다. 그래서 물건을 복사하는 것은 실제적인 문제가 아닙니다.

포인터가 필요하다면 (어쩌면 Type에는 복사 생성자가없고 변경할 수 없습니다.) shared_ptr을 사용하면 못생긴 해킹을하는 것처럼 느껴지 겠지만, 손가락으로 도울 수 있습니다. 예외를 통해 전달 된 정보를 발신자가 문제를 식별하고 처리하는 데 도움이되는 최소한으로 줄이려고 노력할 것입니다.

편집 : 경우에도,

가 발생 객체가 클래스 객체의 복사/이동 생성자와 소멸자가 접근 할 수 있어야합니다 : 나는 C++ standard의 관련 섹션, 섹션 15.1, 제 5 항 발견 복사/이동 작업이 생략됩니다.

그래서 실제로 복사 생성자없이 예외 객체를 throw하는 것은 합법적이지 않습니다.

+0

예를 들어, 나는 여러 복사본들 사이의 예외 콜 스택을 전달하기 위해'shared_ptr'을 사용합니다. –

관련 문제