2012-04-11 2 views
11

나는 약간 불편한 문제를 접하게되었습니다. C++에서는 객체가 던져지면 먼저 임시 객체에 복사되고 임시 객체는 catching 코드로 전달됩니다. 복사본에는 개체의 클래스 복사 생성자가 사용됩니다. AFAIK, 즉 클래스에 전용 복사 생성자가 있으면 예외로 사용할 수 없습니다. 그러나 VS2010에서 다음 코드가 컴파일되어 실행됩니다.개인용 사본 생성자가있는 객체를 던질 수 있습니까?

class Except 
{ 
    Except(const Except& other) { i = 2; } 
public: 
    int i; 
    Except() : i(1) {} 
}; 

int main() 
{ 
    try 
    { 
     Except ex1; 
     throw ex1;   // private copy constructor is invoked 
    } 
    catch (Except& ex2) 
    { 
     assert(ex2.i == 2); // assert doesn't yell - ex2.i is indeed 2 
    } 
    return 0; 
} 

이 방법이 적합합니까?

+0

시도를 생략하더라도 호출 순서를 보면 어쩌면 상황이 정확히 생각한대로 실행되지 않을 수도 있습니다. – selalerer

+1

VS2010과 동일한 동작을하지만 gcc v4.3.4에서는 [여기] (http://ideone.com/RlOjl)에 실패합니다. – hmjd

+0

임시 개체가 생성되고 복사본이 최적화 된 상태 일 수 있습니다. 반환 값 최적화와 비슷합니다. –

답변

13

그것은 합법적이지 않습니다. 표준

임시 객체의 사용 임시 객체 (12.2)의 사용과 관련된 생성자 와 소멸자의 실행을 제외한 프로그램의 의미를 변경하지 않고 제거 될 수있는 경우 15.1/5

, 핸들러의 예외는 throw 표현식의 인수로 직접 으로 초기화 할 수 있습니다. throw 된 개체가 클래스 개체이고 임시 복사본을 초기화하는 데 사용되는 복사 생성자에 액세스 할 수없는 경우 임시 개체를 제거 할 수있는 경우에도이 부적합합니다. 마찬가지로 해당 개체에 대한 소멸자에 액세스 할 수없는 경우 프로그램은 이 삭제 될 수있는 경우에도 임시 개체가 제거 될 수있는 경우에도 이 잘못되었습니다.

+0

놀랍습니다. 결코 일어날 수 없을 것이라고 추측했을 것입니다. 고맙습니다. – petric

2

아니요.

15.1.5 throw 된 객체가 클래스 객체의 복사/이동 생성자이고 소멸자가 접근 할 수 있어야합니다, 복사/이동 작업은 인쇄 또는 디버깅을 추가

관련 문제