你可以合法地将dynamic_cast转换为多态类的非多态基类吗

2024-04-03

In 这个答案 https://stackoverflow.com/a/44329645/1277769,出现了以下场景:

#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根本不是一个非多态类,但我坦率地承认我不是这里发生的事情的专家。

当我尝试相反的方向时:

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

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


是的你可以。

正如 C++ 标准第 §5.2.7/5 中关于表达式的规定dynamic_cast<T>(v):

If T是“指向cv1 B” and v具有类型“指向cv2 D”这样B是一个基类D,结果是一个指向唯一的指针B的子对象D指向的对象v.

还给出了一个例子:

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

正如您所看到的,多态类显然不是唯一的用例dynamic_cast标准允许的。

顺便说一下,cppreference解释一下 http://en.cppreference.com/w/cpp/language/dynamic_cast用不太标准的语言来说:

If new_type是一个指向 Base 的指针或引用,并且类型表达是指向 Derived 的指针或引用,其中 Base 是 Derived 的唯一的、可访问的基类,结果是一个指针或 对派生对象中的基类子对象的引用 指出或识别表达。 (注意:隐式强制转换和 static_cast 也可以执行此转换。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

你可以合法地将dynamic_cast转换为多态类的非多态基类吗 的相关文章

随机推荐