引自C++ Primer 5th 19.2.1。 dynamic_cast运算符


dynamic_cast<type*>(e)
dynamic_cast<type&>(e)
dynamic_cast<type&&>(e)



但是,在这里我写了一个代码片段:
struct A {};
struct B : private A // note: *private* inheritance
{
  A* test() {
    return dynamic_cast<A*>(this);
  }
};

int main()
{
  B b;
  if(b.test()==nullptr)
      throw 1;
}

在上面的代码片段中,A只是B的私有(private)基础,而c++入门并未将其考虑在内。但是,这个代码片段可以被编译并运行,没有错误。底漆写错了吗?

最佳答案

这是所有引物部分的不幸措辞。它把两种类型的类型组合在一起,一个人可以做一个句子,然后把它弄错了。

强制转换为基类,不需要运行时强制转换操作。它是as T.C. says,纯粹是静态构造。就像T.C.用引号括起来,它需要可访问的基数,而不是公共(public)基数。因此,您的代码很好。

对于运行时强制转换(向下转换),C++标准对操作数和动态强制转换所涉及的类型提出了要求,以使其成功。该类必须是公共(public)派生的,否则实现没有义务成功地继承继承链。我的意思是,从理论上讲,它可以使转换成功,但是根据"the runtime check fails"规范,这没有太多余地。

但是,无论哪种方式,程序中都不会出现导致编译失败的错误,也不会导致任何运行时错误。

如果我们将您的代码更改为向下转换而不是向上转换,则这是一个example that doesn't even build:

struct A {};
struct B : private A // note: *private* inheritance
{
  A* test(B* p) {
    return dynamic_cast<A*>(p);
  }

  friend B* foo(A*);
};

B* foo(A* a) {
    return dynamic_cast<B*>(a);
}

int main()
{
  B b;
  *foo(&b);
}
ABfoo的可访问基础,但是, Actor 表格式错误。

将使入门恢复正常的最小更改是将“从目标类型派生的公开的类类型”转换为“从目标类型派生的可访问的类类型”。由于publicly available errata中没有任何内容,我们可以猜测这是一个尚待指出的编辑错误。

10-05 18:26