2012-04-30 4 views
4

다음 프로그램을 사용하여 소멸자에서 exit()를 호출합니다. main() 내부에서 sample 타입의 객체를 만들 때 소멸자는 한 번 호출되고 프로그램은 정상적으로 종료됩니다. 그러나 샘플 형식의 전역 개체를 만들 때 "Destructing .."이 무한히 인쇄됩니다. 누구든지 설명 할 수 있을까요?exit 및 전역 객체 사용

#include "iostream" 
#include "conio.h" 

using namespace std; 

class sample 
{ 
     public: 
    ~sample() { 
        cout <<"Destructing.."<<endl; 
        exit(0); 
       } 
}; 

sample obj; 

int main() 
{ 
getch(); 
} 
+0

어떤 컴파일러를 사용하고 있습니까? – delicateLatticeworkFever

+2

아마도 turboc을 사용하고 있으므로 피해야하며 conio.h 기능을 사용하지 마십시오. – phoxis

+0

M은 Dev-C++을 사용합니다. GCC 컴파일러 –

답변

2

exit() 기능은 세계 모든 개체에 대한 소멸자를 호출하는 프로그램을 받고있다. 그리고 클래스의 소멸자가 exit(1);을 호출하는 시점에서 객체가 아직 소멸 된 것으로 간주되지 않기 때문에 소멸자가 다시 호출되어 무한 루프가 발생합니다.

class sample { 
    bool exiting; 
public: 
    sample() { exiting = false; } 
    ~sample() { 
     cout << "Destructing.." << endl; 
     if(exiting) return; 
     exiting = true; 
     exit(0); 
    } 
}; 

을하지만 소멸자 호출 exit()있는 것은 나쁜 생각 :

이 멀리 얻을 수 있습니다. 이러한 대안 중 하나를 고려하십시오

  • 는 "프로그램이"완료 될 때까지 실행되는 함수를 작성하고 main()
  • 사용 abort() 대신에게에서 호출 종료에 대해 별도의 일반 (비 소멸자) 메소드를 만들 exit() (감사합니다 goldilocks이 하나를 언급했다). abort()exit()이 호출되고 main()이 반환 될 때 정상적으로 수행되는 정리 작업을 모두 무시합니다. 그러나 프로그램에서 특정 정리 작업이 매우 중요 할 수 있으므로 반드시 좋은 생각은 아닙니다. abort()은 이미 너무나 나쁜 오류 만 제외하면 정리를 우회해야합니다.

나는 이전에 예외를 제안했지만 내부 소멸자로부터 예외를 던진 것에 대해 기억하고 마음을 바꿨다. here's why.

참고 또한, 행동이 일치하지 않습니다 - 일부 컴파일러/환경이 무한 루프가 발생, 일부는하지 않습니다. 소멸자의 어느 지점에서 객체가 파괴 된 것으로 간주되는지를 알 수 있습니다. 나는 표준이 이것을 커버하지 못하거나이 경우의 행동이 정의되지 않았다고 말한다.

+0

을 사용하여 왜 asker와 같은 효과를 얻지 못합니까? – phoxis

+0

컴파일러가 더 똑똑하기 때문에 – delicateLatticeworkFever

+0

인데'gcc '가있는'-O0'을 사용하는 경우에도 한 줄만 인쇄됩니다. – phoxis

1

귀하의 파괴 및 소멸자 차례 차례 (네, 아주 긴 시간 동안 계속) ... 호출 종료를 호출 파괴 소멸자를 호출 종료를 호출합니다. 무슨 일

2

나는 소멸자에서 그 일을하는 것은 나쁜 디자인의 표시라고 마이클 슬레이드에 동의합니다. 그러나 그렇게해야 할 적절한 이유가 있다고 생각한다면 (예 : 개발 문제) exit(0) 대신 abort()을 사용하십시오. 이렇게하면 소멸자가 더 이상 호출되지 않고 순환 루프에서 빠져 나오지 않게됩니다.