c++ dynamic_cast error handling
是否有任何与dynamic_cast错误处理相关的良好做法(除非不需要时不使用它)? 我想知道我应该如何处理NULL并抛出bad_cast。
我应该同时检查两者吗? 而且,如果我抓到bad_cast或检测到NULL,我可能还是无法恢复...
现在,我使用断言来检查dynamic_cast是否返回了非NULL值。 您是否会接受代码审查的此解决方案?
如果
1 2 | assert(dynamic_cast<T*>(o) == static_cast<T*>(o)); return static_cast<T*>(o); |
这样,您将在调试版本中检测错误,同时避免发行版本中的运行时开销。
如果怀疑强制转换可能失败并且想要检测到它,请使用
1 2 | T& t = dynamic_cast<T&>(o); t.func(); //< Use t here, no extra check required |
仅在上下文中使用0指针时,才将
1 2 3 4 | if (T* t = dynamic_cast<T*>(o)) { t->func(); //< Use t here, it is valid } // consider having an else-clause |
使用最后一个选项,如果
要直接回答您的问题:我希望我给出的两个第一种选择之一是在代码中具有显式的
仅在投射引用时抛出bad_cast
1 | dynamic_cast< Derived & >(baseclass) |
强制转换指针时返回NULL
1 | dynamic_cast< Derived * >(&baseclass) |
因此,无需检查两者。
断言是可以接受的,但是很大程度上取决于上下文,然后,对于几乎所有断言来说都是如此……
是的,没有。
在调试阶段,
但是,以下顺序:
1 2 3 4 5 6 | if (T1* t1 = dynamic_cast<T1*>(o)) { } if (T2* t2 = dynamic_cast<T2*>(o)) { } if (T3* t3 = dynamic_cast<T3*>(o)) { } |
表示应该通过多态性和虚函数解决的非常糟糕的设计。
这取决于... ;-)
如果我真的希望
但是,如果我要查询多态类型以获取接口不一定要实现的某些功能,那么我将使用指针强制转换,然后NULL不会是一个错误(除非当然,我希望确实能够使用该功能-但后来我就去找了参考演员……)
我同意"取决于"的答案,并添加"优美的降级效果":仅仅因为某个地方的转换失败不足以让应用程序失败(并且用户失去工作等)。我建议结合断言和防御性编程:
1 2 3 4 5 6 | ptr = dynamic_cast<MyClass>(obj); ASSERT(ptr); if(ptr) { // do stuff } |