2016-09-06 3 views
1

typename T 포인터를 포함하는 shared_pointer 템플릿을 구현하고 있습니다. 공유를 수신하는 복사 생성자 (Base 클래스 (T)의 포인터 사용)를 구현하려고합니다. 포인터 클래스 (파생 클래스 (O)에 대한 포인터를 보유). 어떻게 수신 된 포인터를 기본 유형에서 shared_ptr로 캐스트 할 수 있습니까?템플릿 파생 클래스에서 템플릿 기본 클래스로 캐스팅

template <typename T> 
class Shared_Ptr 
{ 
public: 
    template <typename O>friend class Shared_Ptr;  
    template <typename O> 
    Shared_Ptr(const Shared_Ptr<O>& other_); 
private: 
    struct PtrVal 
    { 
     PtrVal(T* ptr); 
     ~PtrVal(); 
     T *m_ptr; 
     size_t m_count; 
    }; 

    PtrVal *m_val; 
}; 

어떻게 복사 생성자를 구현할 수 있습니까 ??

template <typename T> 
template <typename O> 
Shared_Ptr<T>::Shared_Ptr(const Shared_Ptr<O>& other_): 
m_val(static_cast<const Shared_Ptr<T> >(other_).m_val) 
{} 

이 코드는 컴파일 할 때 실행시에 세그먼트 오류 (코어 덤프 됨)를 제공합니다.

내가 다른 해결책을 찾았지만 정말 못생긴 : 내가 (대신 O의 *의) T의 *에 other_의 m_ptr를 변환 한 후 T

Shared_Ptr<T>::Shared_Ptr(const Shared_Ptr<O>& other_) 
{ 
    if(dynamic_cast<T *>(other_.m_val->m_ptr)) 
    {} 

    m_val = (Shared_Ptr<T>::PtrVal *)other_.m_val; 
} 

어떤 제안을 m_val하는 O의 m_val 캐스팅 더 나은 무엇인가? 는

+0

소스 코드에서 boost :: shared_ptr 및 std :: shared_ptr을 살펴보십시오. 삭제 기가 제어 블록에 저장된다는 것을 알 수 있습니다 (이는 유형 삭제에 중요합니다). –

+0

당신은 용어로 더 정확해야합니다, 당신이 부르는 사본은 하나가 아닙니다. – Slava

답변

0

당신은 어떤 상속 관계가 없습니다 other_Shared_Ptr<O> 때문에 Shared_Ptr<T>m_ptr를 캐스팅 할 감사드립니다.

template <typename T> 
template <typename O> 
Shared_Ptr<T>::Shared_Ptr(const Shared_Ptr<O>& other_): 
    m_val (static_cast<T*>(other_.m_val->m_ptr)) 
{} 

또한 카운터를 업데이트해야합니다.

+0

좋은 생각이 아니라면 포인터가 파생 된 것으로 변환 된 기본 포인터가 될 수 있습니다. – Slava

+0

@Slava 유형 검사가 없기 때문에 이것은 나쁜 아이디어라고 생각합니다. 나는 단지 물어 본 질문에 대답한다. Shkopa는이 "캐스트 생성자"라고 할 때 그가하는 일을 알고 있을지도 모릅니다. – billx

+0

그런 다음'static_cast'없이 제대로 작동 할 수 있기 때문에 잘못 대답했습니다. – Slava

관련 문제