shared_ptr, 구독, 소멸자
-
20-09-2019 - |
문제
응용 프로그램 전체에서 Boost/Shared_PTR 포인터를 사용하고 있습니다. 객체에 대한 마지막 참조가 해제되면 shared_ptr은 객체를 삭제합니다. 응용 프로그램의 객체는 관찰자/가입자 패턴과 유사한 응용 프로그램의 중앙 위치에서 이벤트를 가입합니다.
객체 파괴자에서 객체는 구독 목록에서 구독을 취소합니다. 구독 목록은 본질적으로 a입니다 list<weak_ptr<MyObject> >
. 내가하고 싶은 것은 이것과 비슷한 것입니다.
Type::~Type()
{
Subscriptions::Instance()->Remove(shared_from_this());
}
여기서 내 문제는 Shared_from_이 소멸자에서 호출 할 수 없으므로 위의 코드는 예외를 던질 수 있다는 것입니다.
기존 구현에서 구독 목록은 포인터 목록 일뿐입니다. 그러나 수동 메모리 관리로 메모리를 망칠 위험을 줄이기 위해 약한 _ptr 참조를 사용하고 싶습니다.
객체 삭제를하기 위해 shared_ptr에 의존하기 때문에 코드에는 논리적으로 구독 취소 전화를 걸 수있는 단일 장소가 없습니다.
이 상황에서해야 할 일에 대한 아이디어가 있습니까?
해결책
- 구독 인스턴스를 통해 객체를 파괴 할 수 있다면 포인터를 자동으로 제거합니다.
- 구독에서 제거하는 것을 잊을 수 있습니다.
- 모든 객체에 고유 ID를 할당 한 다음 shared_ptr이 아닌 고유 ID를 통해 제거 할 수 있습니다.
- 공유 된 것 대신 제거하기 위해 일반적인 포인터를 전달할 수 있습니다. "ID"역할을합니다.
다른 팁
내 문제는 여기입니다
shared_from_this
위의 코드는 예외를 던지므로 소멸자로 호출 할 수 없습니다.
예외가 발생합니다 만료 되었기 때문에, 정의상, 소멸자.
그래서 어쨌든 당신은 무엇을 원하십니까? "만료 된"공유 포인터? 빈 공유 포인터를 만듭니다.
또는 만료 된 약한 포인터?
"문제"가 shared_from_this
던지기 (증상이지만) 모든 소유자 본질적으로 이미 재설정되거나 파괴되었습니다 그 시점에서 약한 포인터가 만료되고 빈 기본값에 해당하는 약한 포인터가 약한 포인터 (*)를 만들었으므로 기본 초기화 된 약한 포인터를 전달해야합니다.
또한 Subscriptions::Instance()->Remove(weak_OR_owning_pointer)
약한 포인터를 무엇이든 비교할 수 없기 때문에 어느 쪽이든 (약하거나 소유권을 소유 한 포인터) 어떤 식 으로든 의미가 없습니다. 만 잠금을 시도한 다음 비교할 수 있습니다.
따라서 만료 된 약한 포인터를 제거 할 수 있습니다. 의 주장 Remove
쓸모가 없습니다.
(*) 또는 당신은 파괴되는 물체의 이중 소유권의 매우 심각한 이중 버그를 가지고 있습니다!