2012-03-30 1 views
1

자,이 문제에 대해 들었습니다 : 파생 클래스에 대한 포인터를 던져서 기본 포인터를 잡을 수있는 이유는 무엇입니까?하지만 shared_ptrs로는 그렇게 할 수 없습니까?C++ : base의 derived_ptr을 파생하고 catch하는 중 shared_ptr을 가져 오는 중입니까?

class Base {}; 
class Derived : public Base {}; 
int main() 
{ 
    try 
    { 
     throw new Derived() ; 
    } 
    catch(const Base2 * b) 
    { 
     printf("Received a base") ; 
    } 

    return 0 ; 
} 

을하지만이

int main() 
{ 
    try 
    { 
     throw std::tr1::shared_ptr<Derived>(new Derived()) ; 
    } 
    catch(const std::tr1::shared_ptr<Base> & b) 
    { 
     printf("Received a base") ; 
    } 
    return 0 ; 
} 

어떤 아이디어를하지 않는 :

예,이 작품? 그래서 템플릿이 명시 적으로 제공하지 않는 다른 하나로부터 암시 적 변환이 없습니다 derivedbase 관련이 경우에도, shared_ptr<derived>shared_ptr<base> 관련이 없습니다 (같은 본질적으로 다른를 적용 :

+0

내 생각에 예외 처리기가 신경 쓰는 한'shared_ptr '은'shared_ptr '의 서명과 일치하지 않을 것입니다. –

+2

왜 throw/catch와 함께 포인터를 사용하고 있습니까? 나쁜 습관입니다. – Torsten

+0

나는 이것이 가능할 방법을 볼 수 없다. 본문과 핸들러 std :: 함수를 사용하여 함수를 래핑하지 않아도 일반적으로 구성 할 수 있습니다. 일반적으로 catch 할 수 없습니다. – sehe

답변

2

두 번째 예가 효과가 없다고 맞습니다.

예외 처리기는 예외를 매우 명확하게 정의 된 방식으로 만 catch합니다. 특히, 잡을 때 암시 적 변환을 수행 할 수 없습니다. 파생 - 기반 및 포인터 - 기반 변환에서 포인터 - 기반 변환 만 적용됩니다. shared_ptr<derived>shared_ptr<base>에서 파생되지 않으며 기본 제공 포인터가 아니므로 일치하지 않습니다.

shared_ptr<base>을 잡으려면 던지기 전에 shared_ptr<base>으로 변환하십시오.

5

그 이유는 아주 간단합니다 동일한 방법으로 인스턴스화 된 템플릿).

그러나 예외적으로 어떤 문제를 해결하려고하는지 잘 모르겠습니다. 일반적으로 포인터가 아닌 객체를 던지고 싶으므로 const 참조를 받고 싶습니다. 동일한 예외 객체에 대해 여러 포인터를 가질 가능성이 없기 때문에 shared_ptr<exception_object>으로 어떤 문제를 해결할 수 있을지 확신 할 수 없습니다.

+0

@NicolBolas : 좋습니다. 고맙습니다. –

+1

사실, 당신은 문제가 '무효 FUNC (const를 shared_ptr의 &); ... FUNC (shared_ptr의 (없이이 작업을 수행 할 수 을 shared_ptr는 할 shared_ptr의 에서 암시 적 변환이 _is_ 새로운 파생())); ' – hasvn

관련 문제