【问题标题】:Why does the compiler complain about my dynamic_cast? [closed]为什么编译器会抱怨我的 dynamic_cast? [关闭]
【发布时间】:2019-06-16 04:29:42
【问题描述】:

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

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 是空指针)。谁能帮我理解为什么会这样?

【问题讨论】:

  • 请注意,您返回的是 X* 而不是 Y*
  • 对不起,我没明白这个问题,所以最后一行代码将返回一个 D*,但由于 D 是 A 的子类,应该没问题,对吧?
  • 问题是fun 无法从B* 隐式转换为D*dynamic_cast 返回 B*,但您尝试从需要 D* 的函数中返回它。看起来你的意思是让fun 返回Y*
  • 您将指针转换为 base 类,然后尝试将其作为 派生 类指针返回。
  • 我知道了,谢谢!

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


【解决方案1】:
template <class X, class Y>
X* fun(X* p){return dynamic_cast<Y*>(p);}

此函数接受 X* 并返回 X*

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

您得到的错误出现在fun 的主体中,您在其中获取D*,将其转换为B*,然后尝试再次将其隐式转换为D*。那失败了。因此你的错误。

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

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

  2. 查看编译器显示错误所在的行。

解决方法是:

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

现在你的代码可以工作了。

【讨论】:

  • 谢谢!现在我得到了问题。
【解决方案2】:

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

不,不行。 D 开始 A 的子类是无关紧要的。

谁能帮我理解为什么会这样?

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

另一方面,A* p = fun&lt;B,D&gt;(new D()); 格式正确。注意模板参数的不同顺序。但另一方面,fun 并不是很有用的函数。

【讨论】:

  • 我并没有真正写过那个代码(我的教授写过),所以我不应该改变模板参数的顺序。但我现在明白了这个问题。谢谢!!
  • @Diba 好吧,程序格式不正确。如果你不改变某事,那么就没有什么可解决的了。
  • 你说得对,实际上我可以改变的是类的层次结构。我找到了解决方案(B 是 D 的子类),但只是想知道为什么它不能反过来工作。
猜你喜欢
  • 2012-09-12
  • 2016-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-28
  • 2016-11-01
  • 1970-01-01
相关资源
最近更新 更多