为何编译器会抱怨我的dynamic_cast?

时间:2019-01-22 16:39:40

标签: c++ oop templates polymorphism dynamic-cast

我正在尝试找出代码中编译错误的原因:

class A
{
    public:
    virtual ~A(){}
};

class B: public A
{
    public:
    virtual ~B(){}
};

class D: public B
{
    public:
    virtual ~D(){}
};

template <class X, class Y>
X* fun(X* p){return dynamic_cast<Y*>(p);}

int main()
{
    A* q = dynamic_cast<B*>(new D());
    A* p = fun<D,B>(new D());
}

在我看来,指针q和p应该指向相同的类型,但是对于p,我遇到了一个编译器错误,提示“从'B *'到'D *'的转换无效”。唯一没有出错的地方是,我以B是D的子类的方式更改了类(因此p是空指针)。谁能帮助我了解为什么会这样?

2 个答案:

答案 0 :(得分:5)

template <class X, class Y>
X* fun(X* p){return dynamic_cast<Y*>(p);}

此函数采用X*并返回X*

在正文中,将其转换为Y*。然后,您尝试将其隐式转换为X*

您得到的错误在于fun的正文中,您在其中取了D*,将其强制转换为B*,然后尝试隐式将其强制转换为{{1 }}。那失败了。因此,您的错误。

查看编译器错误时,它有助于

  1. 将每个语句放在自己的行上。如果该语句很复杂,请将其分解为多个语句。

  2. 看看编译器说的错误所在行。

解决方法是:

D*

现在您的代码可以使用了。

答案 1 :(得分:0)

  

我没问题,所以最后一行代码将返回D *,但是由于D是A的子类,应该可以,对吧?

否,这不行。 D开始与A的子类无关。

  

有人可以帮助我理解为什么会发生这种情况吗?

指向基数(B*Y*的指针不能隐式转换为指向派生(D*X*)的指针。

另一方面,A* p = fun<B,D>(new D());格式正确。请注意模板参数的不同顺序。但另一方面,fun并不是非常有用的功能。