2012-05-28 4 views
5

가능한 중복 :
C++: Delete this?
Object-Oriented Suicide or delete this; 개체가 메모리를 할당 해제 할 수 있습니까?

나는 매우 좋은 책 C++ 입문서를 읽어 ++ C를 배우고 내가 배우고 어떻게 C C와 같은 delete 키워드로 ++ 할당 해제 메모리 free으로합니다. Java와 Pascal에는 메모리를 일시적으로 해제하는 메커니즘이 없습니다. 오랜 시간 동안 실행되고 필요한 변수가 파괴되면 프로그램에서 오류가 발생할 수 있기 때문에 평범하지 않아야합니다.

간단히 말해서 C++에서 변수가 this.delete()이고 자체가 인 경우 합법적인지 또는 권장 가능한지 궁금합니다. 우리는 대부분 C 및 C++에서 포인터를 해제하는 것에 대해 듣습니다.이 작업은 새로운 freedelete 키워드로 완료됩니다. 파스칼도 포인터를 가지고 있지만 자바는 그렇지 않다. 그래서 Java에서는 객체를 명시 적으로 삭제하지 않아야합니다. C는 객체가 없기 때문에 structfree을 할당 할 수 없었습니다. C가 객체를 가지고 있지 않고 파스칼을 지원하지 않기 때문에 기술적으로 가능하더라도 할당되었습니다. .

그래서 나는 그 개체가 this.delete()과 같은 것으로 자체를 지우는 것이 합법적인지 의문점으로 C++을 떠난다 고 생각합니까?

+0

하긴 g 그래서 가능하다 -'delete this;'는 C++에서 완벽하게 유효한 문법이고 "올바르게"컴파일하고 실행해야한다. 그러나'* this'는 힙에 할당되어 있다고 가정합니다. 또한 일단 메모리 공간이 없어지면 이전 메모리 할당으로 다시 사용할 수 있기 때문에 메모리 손상을 초래할 수 있습니다. 나쁜 생각. 도망쳐 라! 도망쳐 라! –

답변

6

개체가 할 수있는 일은 완벽하게 delete this;입니다.

그러나 이렇게 한 다음 this을 사용하면 정의되지 않은 동작입니다. 당신이 이후에 수행 된 매우주의 경우

그래서, 그것은이 있음을 의미합니다 특히 때문에, 정말 좋은 생각이 아니다, delete this;

을 수행하여 "자살"에 개체에 대한 벌금과 법적이다 그러나 은 새로운으로 시작해야합니다. te 스택에 할당하면 소멸자가 두 번 호출 될 수 있습니다.이 값을 삭제하면 컨텍스트를 벗어날 수 있습니다.

class A 
{ 
public: 
    ~A() { std::cout << "Destructor"; } 
    void foo() { delete this; } 
}; 

int main() 
{ 
    { 
     A a; 
     a.foo(); // OK, a is deleted 
    } // Going out of context, the destructor is called again => undefined behavior 
    return 0; 
} 
+0

답변 해 주셔서 감사합니다. 나는 C++에서 다른 언어와 비교하여 "undefined bevaviour"를 위험하게하는 것은 드문 일이 아니라는 것을 알아 차렸다. –

+1

@NickRosencrantz : 프로덕션 코드에서 정의되지 않은 동작을 기꺼이 감내하는 것은 극히 드문 일입니다. – NPE

+3

@NickRosencrantz : 대부분의 다른 언어에서 정의되지 않은 동작 *이 없습니다. C++에서는 정의상 신뢰도가 떨어지기 때문에 전염병처럼 피해야합니다. 정의되지 않은 동작을 입력하면 프로그램을 신뢰할 수 없습니다. – jalf

5

this이다. 적절한 구문은

delete this; 

것 그리고 네, 그것은 가능하지만 사용하지 못할 개체에 개체 포인터를 렌더링합니다.

좋은 판독 값은 this을 참조하십시오.

실제적으로이 기술을 사용하는 것은 코드 냄새입니다. 사용자가하는 일을 절대적으로 확신하지 않는 한.

+0

재미 있고 잘 알고 있습니다. 답변 해주셔서 감사합니다. –

+0

@NickRosencrantz, 도와 줘서 기쁩니다! –

3

내 질문에 객체가 this.delete 같은() 자체를 삭제하는 것이 합법적인지 여부 : 그것은 좋은 생각이 아니다 왜

다음의 예를 보여줍니다?

기술적으로는 객체가 delete this을 수행하는 것이 합법적입니다.그러나 상당히 많은 중요한 경고가 있습니다 (explained in the FAQ).

delete this은 매우 좁은 기술적 인 문제를 해결한다는 점도 이해해야합니다. 메모리 관리 및 가비지 수집에 관한 큰 그림 문제는 실제로 해결되지 않습니다. 추가 연구에 합당한 한 방향은 the use of smart pointers in C++입니다.

0

이상한 사용 사례는 사용자가 확인을 클릭하거나 대화 상자가 대화 상자를 삭제할 수있는 대화 상자를 말하지만 합법적입니다.

물론 this 포인터는 더 이상 유효하지 않으므로 사용하지 마십시오.

0

개체가 자체 메모리를 할당 해제하는 것은 전적으로 가능합니다. 그러나, 아주 드물게, 명백한 이유를 위해, 사용된다.

가장 많이 사용되는 방법은 참조 카운트 된 메모리 관리를 구현하는 것입니다. 호출자가 release()을 호출하고 참조 횟수가 0이되면 개체가 삭제됩니다. 이 변수는 멤버 변수 내에서 발생하므로 this 포인터를 사용하여 인스턴스를 삭제합니다 (객체 외부에서 delete foo과 같은 방식으로). 예를 들어 :

int release() 
{ 
    OSAtomicDecrement32(&m_refCount); 
    if (m_refCount <= 0) 
    { 
     delete this; 
    } 
    return m_refCount; 
} 

은 (당신이 언급 구문이 유효하지 않습니다 - delete 키워드가 아닌 방법이며, this 포인터입니다.)

마음에 생각해야 할 몇 가지주의 사항이있다 . 이 삭제가 호출되면 this 포인터가 더 이상 유효하지 않으며 데이터 멤버도 없습니다. 이 시점 이후에는 인스턴스가 아닌 참조 만 만들 수 있습니다 (예 : 로컬 변수, 정적 메서드 및 데이터 등).

0

객체가 메모리 자원 Aquisition라는 것을 사용하고 삭제하는 또 다른 방법은 없습니다 new 또는 delete 오브젝트 할이 방법으로 초기화 RAII

입니다. 소멸자는 범위를 벗어날 때 자동으로 호출됩니다.

즉, 당신은 같은 기능에 RAII을 사용 :

void foo()

{

`Object a;` 

    `int i = a.SomeMethod();` 

    `// a's destructor automatically gets called when the function is out of scope` 

}

Further Reading