检查交叉投射是否可行?

tem*_*def 8 c++ static-analysis dynamic-cast cross-cast

我知道dynamic_cast在类层次结构中进行"交叉投射" 是合法的.例如,如果我有类似这样的类:

  A   B
   \ /
    C
Run Code Online (Sandbox Code Playgroud)

如果我有一个A*指向类型对象的指针C,那么我可以使用

A* aPtr = /* ... something that produces a C* ... */
B* bPtr = dynamic_cast<B*>(aPtr);
Run Code Online (Sandbox Code Playgroud)

获取指向我指向的B基础对象的C指针.

我提到这一点的原因是,在我写上面的代码的时候,它可能是编译器目前还没有看到的定义C,即使它看到的AB.这意味着编译器可能没有检测到A和之间的任何类型的连接B,但它仍然必须编译代码,因为它可能C存在类似的存在以及dynamic_cast在某些情况下成功.

问题是这意味着我可能会意外地交叉转换为错误类型的对象.假设我有类似这样的类:

A   B    D
 \ /   
  C
Run Code Online (Sandbox Code Playgroud)

在这里,D是一些随机无关的类.如果我尝试写这样的东西:

A* aPtr = /* ... get a C* pointer ... */
D* dPtr = dynamic_cast<D*>(aPtr);
Run Code Online (Sandbox Code Playgroud)

那么这dynamic_cast将始终在运行时失败,因为有连接没有可能的方式AD.如果D因为我打算使用而意外使用B,编译器将不会给我任何指示我有无意义的演员.

我的问题是:是否有某种方法可以让编译器警告我演员在运行时总会失败? 对于可以检测到这种情况的任何主要编译器,我会对语言级解决方案或某些编译器设置感到满意.如果有外部工具,那也没关系; 我只是想知道是否有可能发现这类错误.

Ben*_*igt 3

在编译时不可能检测到这一点。引入这种关系的类C可以在尚未编写的动态可加载库中找到,并且编译器无法证明其他情况。

但可能也有一些例外。如果A只有私有构造函数(或私有析构函数),那么编译器可以确定不存在未被 命名为友元的新子类A