是否有任何与dynamic_cast错误处理相关的良好实践(除非您不必使用它)?我想知道我应该如何处理NULL和它可以抛出的bad_cast。 我应该检查两者吗?如果我捕获bad_cast或检测到NULL,我可能无法恢复... 现在,我正在使用assert来检查dynamic_cast是否返回NULL值。你会在代码审查中接受这个解决方案吗?

有帮助吗?

解决方案

如果dynamic_cast 应该成功,那么最好使用boost::polymorphic_downcast,这有点像这样:

assert(dynamic_cast<T*>(o) == static_cast<T*>(o));
return static_cast<T*>(o);

这样,您将检测调试版本中的错误,同时避免发布版本中的运行时开销。

如果您怀疑演员可能失败并想要检测它,请使用bad_cast并转换为引用类型。如果出现错误,此演员表将抛出if,并将取消您的程序。 (如果,正如你所说,无论如何你都不会恢复,这是好事。)

T& t = dynamic_cast<T&>(o);
t.func(); //< Use t here, no extra check required

仅当0指针在上下文中有意义时才使用assert指针类型。您可能希望在<=>中使用它:

if (T* t = dynamic_cast<T*>(o)) {
    t->func(); //< Use t here, it is valid
}
// consider having an else-clause

使用最后一个选项,如果<=>返回0,则需要确保执行路径有意义。

直接回答你的问题:我更喜欢我在代码中明确<=>的两个首选方案之一:)

其他提示

仅在投射引用

时抛出bad_cast
dynamic_cast< Derived & >(baseclass)

在转换指针时返回NULL

dynamic_cast< Derived * >(&baseclass)

所以从来没有必要同时检查两者。

断言是可以接受的,但这在很大程度上取决于上下文,那么,对于几乎每个断言都是如此......

是和否。

boost::polymorphic_downcast<>肯定是在调试阶段处理dynamic_cast<>错误的好选择。但是值得一提的是,只有在可以预测在编译时传递的多态类型时才应该使用polymorphic_downcast<>,否则应该使用<=>代替它。

然而是一系列:

if (T1* t1 = dynamic_cast<T1*>(o)) 
{ }
if (T2* t2 = dynamic_cast<T2*>(o)) 
{ }
if (T3* t3 = dynamic_cast<T3*>(o)) 
{ }

表示一个非常糟糕的设计,应该由多态虚函数来解决。

这取决于......; - )

如果我真的希望dynamic_cast给我一些可用的东西,例如如果我和其他人没有将多态类型添加到指向基类的指针的容器中,那么我会使用引用转换并让它std::bad_cast杀死我的应用程序 - 真的没有别的事可做。

但是,如果我查询某个接口所暴露的某些功能的多态类型,它不一定要实现,那么我会使用指针转换,然后NULL就不会出错(当然,除非我期望真的的能力在那里 - 但是那时我已经去了参考演员......)

我同意'它依赖'的答案,并且还添加<!>“优雅降级<!>”:只是因为某个地方的某个地方失败并不足以让该应用程序失败(并且用户失去他/她的工作等)。我建议结合断言和防御性编程:

ptr = dynamic_cast<MyClass>(obj);
ASSERT(ptr);
if(ptr)
{
   // do stuff
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top