本文介绍了C ++入门是否对使用dynamic_cast产生了错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Quoted from C++ Primer 5th 19.2.1. The dynamic_cast Operator



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



在所有情况下, e 的类型必须是从以下对象公开派生的类类型
是目标类型,是目标类型的公共基类,或与目标
类型相同。如果 e 具有以下类型之一,则强制转换将成功。否则,强制类型转换将失败。


如果对指针类型的dynamic_cast失败,则结果为0。如果对
引用类型的dynamic_cast失败,则运算符将引发异常。键入 bad_cast

In all cases,the type of e must be either a class type that is publicly derived from the target type, a public base class of the target type, or the same as the target type. If e has one of these types, then the cast will succeed. Otherwise, the cast fails.
If a dynamic_cast to a pointer type fails, the result is 0. If a dynamic_cast to a reference type fails, the operator throws an exception of type bad_cast

但是,我在这里写了一个代码段:

However,here I've written a code snippet:

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 的私有基础,而c ++入门并未将其考虑在内。但是,此代码段可以编译并运行而不会出错

In the code snippet above, A is just a private base of B, which is not taken into account by the c++ primer. However, this code snippet could be compiled and run without error. Has the primer made a mistake?

推荐答案

这是所有引物部分的不幸措辞。它把两种类型的强制转换组合在一起,一个句子可以完成一个句子,然后把结果弄错了。

This is all in all an unfortunate phrasing on the primers part. It bunched the two types of casts one can do into one sentence, and then misspoke as a result.

强制转换为基类,不需要运行时强制转换操作。它是T.C的,纯粹是静态构造。就像T.C.引用起来,它需要一个可访问性基础,而不是公共基础。因此,您的代码也很好。

Casting to a base class, doesn't require a runtime cast operation. It is, as T.C. says, purely a static construct. And like T.C. quoted, it requires an accessbile base, not public one. So your code is all good and well.

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

For a runtime cast (a downcast) the C++ standard places a requirement on the operand and the types involved in a dynamic cast in order for it to succeed. The class must be publicly derived, otherwise the implementation isn't obligated to make a successful cast down the inheritance chain. I mean, it could in theory make the cast successful, but according to the specification "the runtime check fails", which doesn't leave much leeway.

但是,无论哪种方式,您都没有错会导致编译失败的程序,也不会导致任何类型的运行时错误。

But either way there's nothing wrong in your program that would make it fail to compile, nor is there anything there that would cause any sort of runtime error.

如果我们将您的代码更改为向下转换,而不是向上转换,这是一个甚至没有构建的:

If we change your code to cast down, and not cast up, here's an 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);
}

A B foo 中可访问的基数,但是强制转换格式错误。

A is an accessible base of B in foo, and yet, the cast is ill-formed.

将使入门重新回到正常状态的最小变化是将变成公开的类类型从目标类型 派生到是从目标类型可访问派生的类类型 。由于公开可用的勘误,我们可以猜测这是一个尚待指出的编辑错误。

The minimal change which will bring the primer back on course is to turn "a class type that is publicly derived from the target type" into "a class type that is accessibly derived from the target type". Since there's nothing of the sort in the publicly available errata, we can guess it's an editorial mistake that is yet to be pointed out.

这篇关于C ++入门是否对使用dynamic_cast产生了错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 07:57