development

"다운 캐스팅"unique_ptr

big-blog 2021. 1. 8. 22:47
반응형

"다운 캐스팅"unique_ptr unique_ptr로


돌아 오는 일련의 공장이 unique_ptr<Base>있습니다. 후드하지만, 그들은 즉, 다양한 파생 된 유형에 대한 포인터를 제공하고 unique_ptr<Derived>, unique_ptr<DerivedA>, unique_ptr<DerivedB>

주어 DerivedA : Derived지고 Derived : Base우리는 다음을 가질 것입니다.

unique_ptr<Base> DerivedAFactory() {
    return unique_ptr<Base>(new DerivedA);
}

내가해야 할 일은 반환 된 포인터를 unique_ptr<Base>파생 된 수준 (원래 내부 수준은 아님 )으로 "캐스트"하는 것 입니다. 의사 코드로 설명하려면 :

unique_ptr<Derived> ptr = static_cast<unique_ptr<Derived>>(DerivedAFactory());

에서 객체를 해제 unique_ptr한 다음 원시 포인터를 캐스팅 unique_ptr하고 원하는 다른 맛에 재 할당하는 함수를 사용 하여이 작업을 수행하려고합니다 ( release호출 전에 호출자가 명시 적으로 수행함).

unique_ptr<Derived> CastToDerived(Base* obj) {
    return unique_ptr<Derived>(static_cast<Derived*>(obj));
}

이것이 타당합니까, 아니면 펑키 한 일이 일어날까요?


추신. 일부 팩토리가 런타임에 동적으로로드되는 DLL에 상주한다는 점에서 복잡한 문제가 추가되었습니다. 즉, 생성 된 개체가 생성 된 것과 동일한 컨텍스트 (힙 공간)에서 삭제되었는지 확인해야합니다. 소유권 이전 (일반적으로 다른 컨텍스트에서 발생)은 원래 컨텍스트에서 삭제자를 제공해야합니다. 그러나 포인터와 함께 삭제자를 제공 / 캐스트해야하는 것 외에 캐스팅 문제는 동일해야합니다.


몇 가지 기능 템플릿을 static_unique_ptr_cast만들고 dynamic_unique_ptr_cast. 포인터가 실제로라는 확신이있는 경우 전자를 사용하고 Derived *그렇지 않으면 후자를 사용하십시오.

template<typename Derived, typename Base, typename Del>
std::unique_ptr<Derived, Del> 
static_unique_ptr_cast( std::unique_ptr<Base, Del>&& p )
{
    auto d = static_cast<Derived *>(p.release());
    return std::unique_ptr<Derived, Del>(d, std::move(p.get_deleter()));
}

template<typename Derived, typename Base, typename Del>
std::unique_ptr<Derived, Del> 
dynamic_unique_ptr_cast( std::unique_ptr<Base, Del>&& p )
{
    if(Derived *result = dynamic_cast<Derived *>(p.get())) {
        p.release();
        return std::unique_ptr<Derived, Del>(result, std::move(p.get_deleter()));
    }
    return std::unique_ptr<Derived, Del>(nullptr, p.get_deleter());
}

기능은에 의해 발신자의 발 아래에서 양탄자를 철수하지 않을 것을 보장하기를 rvalue 참조를 복용 훔치는 (가) unique_ptr당신에 전달.

참조 URL : https://stackoverflow.com/questions/21174593/downcasting-unique-ptrbase-to-unique-ptrderived

반응형