使用dynamic_pointer_cast时不能进行动态强制转换

Cannot dynamic cast when using dynamic_pointer_cast

本文关键字:动态 转换 不能 dynamic pointer cast 使用      更新时间:2023-10-16

为什么这段代码不能工作?

std::shared_ptr<Event> e = ep->pop();
std::shared_ptr<TrackerEvent> t;
t = std::dynamic_pointer_cast<TrackerEvent>(e);

我得到以下错误:

/usr/include/c++/4.6/bits/shared_ptr.h:386: error: cannot dynamic_cast '(& __r)->std::shared_ptr<Event>::<anonymous>.std::__shared_ptr<_Tp, _Lp>::get [with _Tp = Event, __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]()' (of type 'class Event*') to type 'class TrackerEvent*' (source type is not polymorphic)

TrackerEvent继承自Event,所以我想问题是我不能在这个方向上投射。但是ep->pop()可能返回类型为EventTrackerEvent的对象。我希望当我尝试将其转换为TrackerEvent并且它返回NULL时,我会知道我是否有EventTrackerEvent

我该怎么做呢?

编译器在消息末尾告诉你发生了什么:

(源类型不是多态的)

你的Event基类需要至少有一个virtual成员函数(即是一个多态类型),以便允许动态强制转换。可以将Event的析构函数设置为虚函数:

class Event
{
public:
    virtual ~Event() { /* whatever goes here, or nothing... */ }
    // ...
};

这是一个多态类型的实例,显示了代码编译(删除虚析构函数会导致类似于您看到的编译错误)。

正如Luc Danton在注释中正确提到的,虚析构函数的默认版本可以这样定义(如果你的编译器在这方面是c++ 11兼容的):

class Event
{
public:
    virtual ~Event() = default;
    // ...
};

要执行dynamic_cast,要转换的类型必须是多态的。要使其为真,它必须具有或继承一些虚成员。确保Event有一个虚成员函数(至少有一个虚析构函数)。