为什么动态转换仅适用于指针和引用? 说我有这样的东西
struct foo
{
virtual void test(){}
};
struct bar : public foo
{
};
为什么这样的东西行不通
foo* f = new bar();
bar& b = dynamic_cast<bar>(*f); //Fail must be either pointer or reference
现在假设bar
为其父foo有一个转换构造函数。
我的问题是为什么动态转换只接受指针和引用,而不接受像static_cast
这样的简单对象?
答案 0 :(得分:4)
dynamic_cast
仅具有一个目的:沿继承层次结构进行投射,特别是沿层次结构向上和向下进行继承。让我们假设它适用于您的示例中的值,这里将发生什么:
bar b{};
auto sliced = dynamic_cast<foo>(b);
对象sliced
的类型为foo
,但仅包含foo
的{{1}}子对象。这实际上不是您想要的。按值处理多态类型的实例不是一个好的选择,另请参见this thread。
在相反的方向上,这显然不能很好地起作用的原因更加明显:
b
最后一个示例中的注释有点夸张,因为bar b{};
foo& f = b;
// Pass f by value to dynamic_cast?! Then, the argument is already
// sliced before the dynamic_cast is even able to determine its
// runtime type.
bar downcast = dynamic_cast<bar>(f);
是一个运算符而不是一个函数,但是它应该在这里指出问题:跨层次结构的转换在值语义上不能很好地发挥作用,并且dynamic_cast
反映了这一点。
答案 1 :(得分:1)
当两个类的基类B和派生的D之间存在关系(继承)时,动态类型转换起作用。如果我们使用非引用和指针类型,则意味着我们正在转换它们,那么我们需要转换操作符,例如运算符B()或运算符B()并返回您想要的内容。
这里的情况有所不同:我们有一个对象,该对象包含两个部分:1.基本类型2.仅特定于派生类型。 在这里,当我们使用指针或引用进行转换时,它只是将指针切换到正确的部分,并且根据类型,我们知道它可以移动多少地址来访问元素(字段)。