이것은 오래되고 대답 된 질문이지만 @Alexandre는 "왜 이것을 원할까요?"라고 물었고, 오늘 오후에 고려할 사용법의 예를 제공 할 수 있다고 생각했습니다.
레거시 코드. 맨 끝에 삭제 obj와 함께 알몸 포인터 Obj * obj를 사용합니다.
불행히도 때로는 종종 개체를 더 오래 살리기 위해 필요합니다.
참조 카운트 스마트 포인터로 만드는 것을 고려하고 있습니다. 그러나 모든 곳 에서 사용한다면 변경해야 할 코드 가 많이ref_cnt_ptr<Obj>
있습니다. 그리고 벌거 벗은 Obj *와 ref_cnt_ptr을 혼합하면 Obj *가 아직 살아 있더라도 마지막 ref_cnt_ptr이 사라질 때 암시 적으로 삭제 된 객체를 얻을 수 있습니다.
그래서 explicit_delete_ref_cnt_ptr을 만드는 것에 대해 생각하고 있습니다. 즉, 삭제는 명시적인 삭제 루틴에서만 수행되는 참조 카운트 포인터입니다. 기존 코드가 객체의 수명을 알고있는 곳과 객체를 더 오래 살리는 새로운 코드에서 사용하십시오.
explicit_delete_ref_cnt_ptr이 참조 될 때 참조 카운트를 늘리거나 줄입니다.
그러나 explicit_delete_ref_cnt_ptr 소멸자에서 참조 횟수가 0으로 표시되면 해제되지 않습니다.
명시적인 삭제와 유사한 작업에서 참조 횟수가 0 인 경우에만 해제됩니다. 예를 들면 다음과 같습니다.
template<typename T> class explicit_delete_ref_cnt_ptr {
private:
T* ptr;
int rc;
...
public:
void delete_if_rc0() {
if( this->ptr ) {
this->rc--;
if( this->rc == 0 ) {
delete this->ptr;
}
this->ptr = 0;
}
}
};
좋아, 그런 것. 참조 카운트 포인터 유형이 rc'ed ptr 소멸자에서 가리키는 객체를 자동으로 삭제하지 않는 것은 조금 특이합니다. 그러나 이것이 벌거 벗은 포인터와 rc'ed 포인터를 조금 더 안전하게 혼합하는 것처럼 보입니다.
그러나 지금까지 이것을 삭제할 필요는 없습니다.
그러나 그것은 나에게 일어났다 : 포인트가 가리키는 객체가 참조 카운트되고 있음을 알고 있다면, 예를 들어 카운트가 객체 내부 (또는 다른 테이블)에있는 경우, delete_if_rc0 루틴은 (스마트) 포인터가 아닌 pointee 객체.
class Pointee {
private:
int rc;
...
public:
void delete_if_rc0() {
this->rc--;
if( this->rc == 0 ) {
delete this;
}
}
}
};
실제로, 그것은 멤버 메소드 일 필요는 없지만 무료 기능이 될 수 있습니다.
map<void*,int> keepalive_map;
template<typename T>
void delete_if_rc0(T*ptr) {
void* tptr = (void*)ptr;
if( keepalive_map[tptr] == 1 ) {
delete ptr;
}
};
(BTW, 코드가 옳지 않다는 것을 알고 있습니다. 세부 사항을 모두 추가하면 코드가 읽기 어려워 져서 이렇게 남겨 둡니다.)
delete this
클래스와 해당 클래스의 객체를 만드는 데 사용 된 할당 방법 사이에 긴밀한 연결을 만든 경우 입니다. OOP에서 가장 근본적인 것은 호출자가하는 일을 모르거나 신경 쓰지 않는 자율적 인 클래스를 만드는 것이므로 OO 디자인은 매우 열악합니다. 따라서 적절하게 설계된 클래스는 클래스가 어떻게 할당되었는지 알거나 신경 쓰지 않아야합니다. 어떤 이유로 든 특별한 메커니즘이 필요하다면 더 나은 디자인은 실제 클래스 주위에 래퍼 클래스를 사용하고 래퍼가 할당을 처리하게하는 것입니다.