문제

이 질문은 이미 여기에 답이 있습니다.

초기 기본 테스트에서는 완벽하게 안전합니다. 그러나 조작을 시도하는 것은 저를 강타했습니다. this 나중에 함수에서 delete에스 this 런타임 오류가 될 수 있습니다. 이것이 사실이며, 일반적으로 안전합니까? delete this? 아니면 안전한 경우에만 있습니까?

도움이 되었습니까?

해결책

delete this 합법적이고 당신이 기대할 수있는 일을합니다. 그것은 당신의 클래스의 소멸자라고 부르고 기본 기억을 해방시킵니다. 후에 delete this 반환, 당신의 this 포인터 가치 ~ 아니다 변경, 이제는 매달려있는 포인터입니다. ~ 아니다 불쾌감을 느끼십시오. 여기에는 클래스의 멤버 변수를 사용한 암시 적 불균칭이 포함됩니다.

일반적으로 참조 카운트 클래스에서 ref-count가 0으로 감소 할 때 DecrementRefCount()/Release()/모든 멤버 기능이 호출됩니다 delete this.

delete this 일반적으로 여러 가지 이유로 매우 나쁜 형태로 간주됩니다. 실수로 회원 변수에 실수로 액세스하기가 쉽습니다 delete this. 발신자 코드는 객체가 자체 파괴 된 것을 인식하지 못할 수 있습니다.

또한, delete this 코드가 객체 소유권에 대한 대칭 전략이 없을 수도있는 "코드 냄새"입니다. 물체는 자체적으로 할당 할 수 없었습니다 new, 그래서 전화 delete this 클래스 A가 객체를 할당하고 있지만 클래스 B는 나중에 [self]를 해제하고 있음을 의미합니다.

다른 팁

본질적으로 메소드의 마지막 작업 인 한 "this"를 삭제하는 것이 안전합니다. 실제로 여러 전문 수준 API가 그렇게합니다 (예를 들어 ATL의 CcomoBject 구현 참조).

유일한 위험은 "삭제"를 호출 한 후 다른 멤버 데이터에 액세스하려고 시도하는 것입니다. 이것은 확실히 안전하지 않습니다.

다른 사람들이 이미 언급 한 것처럼 이것은 완벽하게 합법적입니다. 아직 언급되지 않은 추가 이유는 위험합니다. 힙에 물체가 할당되었다고 가정합니다. 참조 계산 구현의 경우 일반적으로 문제가되지는 않지만 보장하기가 어려울 수 있습니다.

그러나 소멸자에서하지 마십시오!

다른 사람들이 언급 한 바와 같이, 이것은 유효한 관용구이지만 안전을 위해서는 객체가 스택에 인스턴스화되지 않도록해야합니다.

이를 수행하는 한 가지 방법은 생성자와 소멸자를 개인화하고 클래스 공장 함수를 통해 객체 생성을 시행하는 것입니다. 클래스 공장은 정적 멤버 기능이거나 친구 기능이 될 수 있습니다. 그런 다음 "삭제 삭제"를 수행하는 객체의 delete () 메소드를 통해 정리를 수행 할 수 있습니다. COM 객체는 기본적으로 기준 수가 0으로 감소 될 때 발생하는 "이 삭제 삭제"로 참조 계산 된 것을 제외하고는 기본적 으로이 방식으로 작동합니다.

예. 완벽하게 괜찮아야합니다. "이것은"는 단지 포인터 일뿐입니다. 모든 포인터는 삭제를 위해 수행됩니다. 객체 삭제 방법에 대한 정보는 힙 레코드에 포함되어 있습니다. 이것이 IunkNown :: Release ()가 일반적으로 COM 객체에서 구현되는 방법입니다.

삭제하면 삭제중인 객체의 서브 클래스가있을 때 문제가 발생할 수 있습니다. 구조가 상단에서 시작되고 삭제가 바닥에서 시작되는 것을 기억하십시오. 따라서 삭제되면 이것은 계층 구조의 중간에 있으면 기본적 으로이 특정 클래스 아래의 모든 객체를 잃었습니다.

삭제는 참조 계산 객체를 구현할 때 매우 편리합니다. 그 예는 COM 클래스입니다.

읽다 비슷한 토론을 위해. 당신의 이해는 그것이 효과가 있고 필요하며 나중에 액세스 할 수 없기 때문에 위험 할 수 있다는 점에서 옳습니다.

법적 예
안전한 아니요

기본 클래스에서 상속하고 기본 클래스 함수에서 삭제 한 경우 파생 클래스 포인터를 사용하면 충돌이 발생합니다. 예 :

class Base
{

    virtual void Release()
    {
        delete this;
    }

}

class Derived : public Base
{

    void Foo()
    {
        ...
    }

}

main()
{

    Base *ptrDerived = new Derived();
    ptrDerived->release();
    ptrDerived->Foo() //Crash

}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top