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*到指针在实际存储SPFooInherited到SPFoo.如果此隐式转换不存在,则代码将无法编译,因此shared_ptr不会发生s与不相关类型之间的不安全转换.
函数调用和catch之间的根本区别在于隐式转换将在函数参数的初始化中发生,但是catch只能匹配单个类型(FooInheritedis-a Foo,因此它将匹配).