如何使用dynamic_cast运算符识别失败的强制转换
How to identify failed casts using dynamic_cast operator?
Scott Meyer
在其著作《Effective C++
》中表示,dynamic_cast
用于执行向下或跨继承层次结构的安全强制转换。也就是说,使用dynamic_cast将基类对象的指针或引用强制转换为派生基类对象或同级基类对象的指向或引用,这样就可以确定强制转换是否成功。
失败的强制转换由空指针(强制转换指针时)或异常(强制转换引用时)指示。
我想得到两个代码片段,显示在可以指示强制转换指针和强制转换引用的情况下失败的强制转换。
对于指针,这是一个简单的null检查:
A* a = new A();
B* b = dynamic_cast<B*>(a);
if (b == NULL)
{
// Cast failed
}
对于参考,您可以捕获:
try {
SomeType &item = dynamic_cast<SomeType&>(obj);
}
catch(const std::bad_cast& e) {
// Cast failed
}
根据OP的评论("我不明白Scott提到的强制转换怎么会失败。"),这里真正的问题实际上是:"dynamic_cast
怎么会失败?"
当目标类型与对象的动态类型不匹配时,它就会失败。举个简单的例子:
struct A {
virtual ~A() {}
};
class B : public A {};
int main() {
A *a = new A;
B *b = dynamic_cast<B *>(a); // should fail
if (b == NULL)
std::cout << "First cast failed.n";
A *c = new B;
b = dynamic_cast<B *>(c); // should succeed
if (b == NULL)
std::cout << "Second cast failed.n";
return 0;
}
这里,虽然a
可以指向B
类型的对象,但它实际上确实指A
类型的对象。当我们尝试执行dynamic_cast以使其指向B
时,会失败。在第二次尝试中,我们再次获得一个指针,该指针不仅可以,而且可以指向类型为B
的对象。既然如此,那么在这种情况下,对B *
的dynamic_cast就成功了。
引用情况下的基本情况没有太大变化,只是a
、b
和c
变成了引用而不是指针,我们通过捕获异常来注意到失败(@ReedCopsey已经很好地证明了这一点,我认为我没有任何新的内容要添加)。
下面是一个完整的示例,展示了dynamic_cast
如何无法生成指针。
class A
{
public:
virtual void Foo();
};
class B: public A
{
};
class C: public A
{
};
void test()
{
A a;
B b;
A* pA = &b;
B* pB = dynamic_cast<B*>(pA); // this works OK, returns the expected pointer
C* pC = dynamic_cast<C*>(pA); // this returns NULL because B isn't a C
}
在现实世界中,您将尝试抛出那些不是直接创建的指针,例如,它们可能来自vector
。
相关文章:
- 模板参数替换失败,并且未完成隐式转换
- 分配给转换运算符失败-C++
- 将 const 转换为 const char* 无效,我该如何解决?使用 gcc7 时失败
- PyTorch C++将数据转换为张量失败
- 为什么在此示例中从unique_ptr自动向上转换<derived>到unique_ptr<base>失败?
- 使用静态转换,因为动态转换失败.不好的做法?
- 从 std::vector<double> 到 Python 列表的转换失败(提升 python)
- 从长型转换为相同大小的 int 失败
- 使用提升对字符串进行标记化时,将令牌转换为 char* const* 时失败
- 为什么在此代码中隐式转换为常量迭代器失败?
- 错误:静态断言失败:std ::线程参数必须在转换为rvalues后不可行
- 动态强制转换 (dynamic_cast) 在 OSx (XCode ) 上使用 .dylib 时失败
- C++长到字符串的转换失败
- 将HSV转换为RGB在OpenCV中失败
- QByteArray 转换为十六进制失败
- AIX C++ iconv 转换失败
- 匿名结构可提高函数转换在GCC 5.4上失败
- 将C 方法参数转换为模板参数会因编译错误而失败
- 失败的证明转换字符串到枚举类
- 有没有办法将模板的替换失败转换为布尔值(真/假)或标签(标准::true_type/标准::false_type)