2012-12-11 2 views
2

가능한 중복 :
C++: Delete this?이 전화 소멸자를 삭제할 예정입니까?

이는 foobar는 힙에 생성 된 클래스가있다. 죽을 때 응용 프로그램을 종료하고 싶습니다. die() 함수를 호출하면 죽어야합니다. 힙에 생성 된 일부 개인 속성이 있습니다. 또한 삭제해야합니다.

Foobar::Foobar() 
{ 
    m_var = new int(1); 
} 

Foobar::~Foobar() 
{ 
    delete m_var; 
    exit(0); 
} 

void Foobar::die() 
{ 
    delete this; 
} 

문제는 delete this 일치한다 : 그 코드를 썼다. 전화를 걸면 Foobar::~Foobar()을 부를 것인가, 그렇지 않습니까?

P. 더 나은 해결책이 있다면 제안하십시오.

+2

직접'delete'를 호출하는 대신'die' 함수를 사용해야하는 이유는 무엇입니까? –

+1

운영 체제는 프로세스가 종료 될 때 힙 메모리를 회수하지만보다 일반적으로 명시 적으로 릴리스해야하는 리소스 유형이 있지만이 디자인의 더 나은 근거가됩니다. –

+0

@KarthikT 예. 나는 Qt를 사용하고 die '에 추가 코드가 있기 때문에 호출되어야한다. 또한 실행되어야한다. –

답변

2

new 동적으로 할당 : 예, delete this은 소멸자가 호출되는 원인이됩니다. 그러나 this 삭제시 매우주의해야합니다. 특히 후속 작업이 클래스의 멤버에 액세스하지 못하도록해야합니다.

또한 동적 할당되지 않은 메모리 (예 : new)에서 수행되는 경우 의 정의되지 않은 동작이 발생합니다. 사실 객체가 new[]을 통해 할당 된 경우 정의되지 않은 동작이 발생합니다. http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.15

여기에 대한 또 다른 SO 질문입니다 : Is delete this allowed?

+0

>> 그러나'this'를 삭제할 때는 매우 조심해야합니다. 왜? 그 후 exit (0)을 호출하여 응용 프로그램을 종료하고 어떤 코드도 실행되지 않을 것이라고 생각합니다. 또는 어쨌든 die()는 멤버가 될 수있는 모든 생성 된 객체를 삭제하는 추가 코드를 호출합니다. –

+0

물론,이 경우 안전 해 보입니다. 그러나 일반적으로이 패턴을 사용할 때마다 항상 두 번 생각하고 실제로 안전한지 확인하는 것이 좋습니다. 'delete this '에 의해 암시 적으로'exit'를 호출하면,'exit'를 호출하면 제어권이 원래의 위치로 되돌아 가지 않는다는 것을 의미하므로 실제로 다른 자원이 적절하게 해제되는지 생각할 필요가 있습니다 RAII에서 처리하지 못한 리소스는 누출 될 수 있습니다. – Agentlien

+0

또한, 객체가 어떻게 할당되었는지에 대한 나의 편집을 보아라. (new가 아닌지) (@Chubsdad가 처음 지적했듯이) – Agentlien

2

예. delete은 소멸자를 호출합니다.

this SO 스레드 읽기에 관심이있을 수 있습니다. 객체를 가정


+0

왜 downvote? –

+1

downvote하지 않았지만 좋은 복제본을 발견했습니다. –

1

번호가이 보장되지

은 자세한 내용은이 링크를 참조하십시오. delete은 이 new을 사용하여 생성 된 것이 확실한 경우에만 호출해야합니다.

따라서 현재 개체의 생성 방법에 따라 소멸자가 호출 될 수도 있고 없을 수도 있습니다.

그래서 'Foobar'객체가 스택에 생성되었다고 가정합니다 (즉, new 제외). 그런 다음 delete this에 정의되지 않은 동작이 있습니다.

OTOH가 'new'를 사용하여 생성 된 경우 delete this은 안전하며 소멸자를 호출합니다.

+0

동적 할당에 대한 좋은 지적. 내 대답에 언급하는 것을 잊어 버렸습니다. – Agentlien

+0

나는 이미 그것에 대해 썼다. "Foobar 클래스가 힙에 생성되었다. 죽을 때 응용 프로그램을 종료하고 싶다."** heap **에 생성되었다. –

0

변수가 정의 된 방식에 따라 달라집니다. 변수가 new 키워드로 정의되어야합니다. 그렇지 않으면 이 생성자를 호출하지 않습니다. 변수를 다음과 같이 선언하십시오. foobar a = new foobar();

+0

내가 이미 질문에 대해 썼다 - "Foobar 클래스가 힙에 생성되었습니다. 죽을 때 응용 프로그램을 종료하고 싶습니다 ..." ** heap **에 작성되었습니다. –