为什么动态类型转换仅适用于引用和指针

时间:2019-05-21 08:27:09

标签: c++ casting

为什么动态转换仅适用于指针和引用? 说我有这样的东西

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这样的简单对象?

2 个答案:

答案 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.仅特定于派生类型。 在这里,当我们使用指针或引用进行转换时,它只是将指针切换到正确的部分,并且根据类型,我们知道它可以移动多少地址来访问元素(字段)。