智能指针和异常处理

Ike*_*rdo 8 c++ exception smart-pointers

我已经浏览了互联网,这个主题正在寻找我面临的这种情况的完整答案.我已经读过,向对象投掷智能指针并不是很聪明.我只是想明白为什么会这样.我会解释一下情况.让我们想象一下这个简单的层次结构

class Foo 
{ 
public: virtual ~Foo() {} 
}; 

typedef tr1::shared_ptr<Foo> SPFoo; 

class FooInherited: public Foo { }; 

typedef tr1::shared_ptr<FooInherited> SPFooInherited; 
Run Code Online (Sandbox Code Playgroud)

让我们检查一下这个测试代码:

int main(int argc, char** argv) 
{ 
  try 
  { 
    throw FooInherited(); 
  } 
  catch(const Foo& f) 
  { 
    cout << "Foo& caught!" << endl; 
  } 
  try 
  { 
    throw SPFooInherited(new FooInherited()); 
  } 
  catch(const SPFoo& f) 
  { 
    cout << "SPFoo& caught!" << endl; 
  } 
  return 0; 
} 
Run Code Online (Sandbox Code Playgroud)

一切都编译但在运行时第二次try-catch不会被执行.有人能解释一下为什么吗?特别是如果这样的代码行在运行时完全正常.

void function(const SPFoo& f) 
{ 
} 

... 

SPFooInherited fi(new FooInherited()); 
function(fi);
Run Code Online (Sandbox Code Playgroud)

我确实理解问题是SPFooInherited不从SPFoo继承(即使FooInherited继承自Foo),但它非常想知道什么是编译器/ RTE与函数调用示例的不同之处在于捕获异常不是能够解决de情况.是因为catch参数与函数调用参数不同吗?为什么Foo&works和SPFoo没有?

非常感谢你提前.

此致,伊克尔.

Man*_*rse 13

正如你在问题中所说的那样,SPFooInherited它不是一个子类SPFoo.这意味着catch(SPFoo const&)不会捕获实例SPFooInherited.另一方面,FooInherited是继承自的Foo,因此catch(Foo const&)会捕获实例FooInherited.

要理解这一点,您不需要对编译器或运行时环境有任何特殊的了解.它只是语言的一部分.

调用函数的原因是tr1::shared_ptr有一个模板化的非显式构造函数,它允许在函数调用站点进行隐式转换.

那就是:tr1::shared_ptr有以下构造函数:

//Note the lack of explicit
template<class Y> shared_ptr(shared_ptr<Y> const & r);
Run Code Online (Sandbox Code Playgroud)

这允许shared_ptr从不同的共享指针类型构造a.此构造的实施对隐式转换relys从FooInherited*Foo*到指针在实际存储SPFooInheritedSPFoo.如果此隐式转换不存在,则代码将无法编译,因此shared_ptr不会发生s与不相关类型之间的不安全转换.

函数调用和catch之间的根本区别在于隐式转换将在函数参数的初始化中发生,但是catch只能匹配单个类型(FooInheritedis-a Foo,因此它将匹配).