您可以合法地对多态类的非多态基类进行dynamic_cast转换吗 [英] Can you legally dynamic_cast to non-polymorphic base class of a polymorphic class

查看:111
本文介绍了您可以合法地对多态类的非多态基类进行dynamic_cast转换吗的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此答案中,出现了以下情况:

In this answer, the following scenario came up:

#include <cassert>

struct A {};

struct B { virtual ~B(){} };

struct AA{};
template <class T>
struct C : A, T {};

int main()
{
  B * b = new C<B>;
  AA * aa = new C<AA>;
  assert(dynamic_cast<A*>(b));
  assert(dynamic_cast<A*>(aa)); //this line doesn't compile, as expected
}

在g ++ 4.8.4(Ubuntu)上,此命令进行编译并断言通过.我的问题是,这真的合法吗?我觉得您根本不应该dynamic_cast进入非多态类,但是我自由地承认我不是这里所发生事情的专家.

On g++ 4.8.4 (Ubuntu), this compiles and the assert passes. My question is, is that really legal? I feel like you shouldn't be able to dynamic_cast to a non-polymorphic class at all, but I freely admit that I'm not an expert in what's happening here.

当我尝试相反的方向时:

When I tried the opposite direction:

dynamic_cast<B*>((A*)(new C<B>));

它无法编译,指出源类型不是多态的".我觉得这是一个线索,但是找到属于当前指针所基于的类的非多态基类似乎仍然很费力(那句话有意义吗?).

it fails to compile, stating that "source type is not polymorphic". I feel like that's a clue, but it still seems a stretch to find the non-polymorphic base class that belongs to a class that the current pointer is a base of (did that sentence make sense?).

推荐答案

是的,可以.

正如C ++标准在§5.2.7/5中对表达式dynamic_cast<T>(v)所述:

As the C++ standard says in §5.2.7/5 about the expression dynamic_cast<T>(v):

如果T是指向 cv1 B的指针"并且v具有类型指向 cv2 D的指针",则 BD的基类,结果是指向唯一B的指针 v指向的D对象的子对象.

If T is "pointer to cv1 B" and v has type "pointer to cv2 D" such that B is a base class of D, the result is a pointer to the unique B subobject of the D object pointed to by v.

也给出了一个例子:

struct B { };
struct D : B { };
void foo(D* dp) {
  B* bp = dynamic_cast<B*>(dp); // equivalent to B* bp = dp;
}

如您所见,多态类显然不是标准允许的dynamic_cast的唯一用例.

As you can see, polymorphic classes are clearly not the only use case of dynamic_cast permitted by the standard.

顺便说一句,cppreference 用不太标准的语言来解释:

By the way, cppreference explains it in less standardese language:

如果 new_type 是指向Base的指针或引用,并且类型为 expression 是Derived的指针或引用,其中Base是一个 派生的唯一,可访问的基类,结果是指针或 对派生对象中的基类子对象的引用 指向或由 expression 标识. (请注意:隐式强制转换和 static_cast也可以执行此转换.)

If new_type is a pointer or reference to Base, and the type of expression is a pointer or reference to Derived, where Base is a unique, accessible base class of Derived, the result is a pointer or reference to the Base class subobject within the Derived object pointed or identified by expression. (Note: an implicit cast and static_cast can perform this conversion as well.)

这篇关于您可以合法地对多态类的非多态基类进行dynamic_cast转换吗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆