C ++:抛出派生的shared_ptr并捕获base的base_ptr?

时间:2012-03-30 09:15:48

标签: c++ exception shared-ptr

好的,我被告知这个问题:为什么你可以抛出指向派生类的指针并捕获指向它的基础的指针......但你不能用shared_ptrs做到这一点?

示例,这有效:

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 ;
}

有什么想法吗?

2 个答案:

答案 0 :(得分:5)

原因很简单:即使derivedbase相关,shared_ptr<derived>也与shared_ptr<base>无关,所以没有隐含除非模板明确地提供它,否则从一个转换到另一个(这同样适用于以相同方式实例化的任何其他模板)。

但是,对于例外情况,我不确定您真正想要解决的问题是什么。通常,您想要抛出一个对象(而不是一个指针),并且您希望捕获const引用。由于您不太可能有多个指向同一个异常对象的指针,因此我不确定您使用shared_ptr<exception_object>解决了什么问题。

答案 1 :(得分:2)

你的第二个例子是行不通的。

异常处理程序仅以非常明确定义的方式捕获异常。特别是,捕获时无法进行隐式转换。仅应用派生到基础和指向派生到指针到基础的转换。由于shared_ptr<derived>不是来自shared_ptr<base>,并且它不是内置指针,因此它不匹配。

如果您想抓住shared_ptr<base>,请在投掷前转换为shared_ptr<base>