Sir*_*Guy 16 c++ polymorphism casting
在这个答案中,出现了以下情况:
#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
}
Run Code Online (Sandbox Code Playgroud)
在g ++ 4.8.4(Ubuntu)上,这个编译并且断言传递.我的问题是,这真的合法吗?我觉得你根本不应该dynamic_cast参加一个非多态的课程,但我承认我不是这里发生的事情的专家.
当我尝试相反的方向时:
dynamic_cast<B*>((A*)(new C<B>));
Run Code Online (Sandbox Code Playgroud)
它无法编译,声明"源类型不是多态的".我觉得这是一个线索,但它仍然似乎是一个延伸,找到属于当前指针是基础的类的非多态基类(这个句子是否有意义?).
Chr*_*ckl 13
是的你可以.
正如C++标准在§5.2.7/ 5中所说的那样dynamic_cast<T>(v):
如果
T是"指向cv1的 指针B"并且v具有类型"指向cv2的 指针D",这B是一个基类D,则结果是指向由其指向B的D对象的唯一子对象的指针v.
给出了一个例子:
Run Code Online (Sandbox Code Playgroud)struct B { }; struct D : B { }; void foo(D* dp) { B* bp = dynamic_cast<B*>(dp); // equivalent to B* bp = dp; }
如您所见,多态类显然不是dynamic_cast标准允许的唯一用例.
顺便说一句,cppreference 用较少的标准语言解释它:
如果new_type是Base的指针或引用,并且expression的类型 是Derived的指针或引用,其中Base是Derived的唯一可访问基类,结果是Derived中Base类子对象的指针或引用通过表达指出或识别的对象.(注意:隐式转换和static_cast也可以执行此转换.)