[英]How to initialize a generic base class in c++
我正在尝试重写一些旧代码以使其更加面向对象。 以前我有一个结构体的联合体,比如Event
union Event {
AEvent aEvent;
BEvent bEvent;
CEvent cEvent;
}
并且此Event
稍后在结构中使用
struct EventImpl {
... //some other members
Event event();
}
现在我正在尝试使用强大的shared_ptr
; 我创建了一个名为BaseEvent
的新基类
class BaseEvent{
size_t m_TypeHash;
public:
using Ptr = std::shared_ptr<BaseEvent>;
virtual ~EventDesc() = default;
template <class T>
// cast to different events
static std::shared_ptr<T> Cast(const Ptr& src) {
return src->m_TypeHash == typeid(T).hash_code()
? std::static_pointer_cast<T>(src)
: nullptr;
}
protected:
BaseEvent(size_t typeHash) : m_TypeHash(typeHash){}
};
从这里开始, AEvent
、 BEvent
和CEvent
可以扩展BaseEvent
,这使代码更清晰。
但问题出现了,我如何处理包含Event
的结构EventImpl
?? 有没有办法初始化一个通用的BaseEvent
?
struct EventImpl {
... //some other members
BaseEvent<T> event; //??
T event; // ??
std::shared_ptr<BaseEvent> event; // ???
}
编辑:名称EventImpl
有点误导,正如德米特里指出的那样, EventWrapper
认为更合适。 :)
有很多不同的方法可以做到这一点。 首先,您可以使用std::variant
作为union
的更具OOP意识的替代方案:
using Event = std::variant<AEvent, BEvent, CEvent>;
另一种方法是使用动态多态:您需要为所有XEvent
类型定义一个基类:
class BaseEvent {};
class AEvent : public BaseEvent {};
动态多态的另一个方面是如何返回值:通过原始指针、通过引用、智能指针等。 std::shared_ptr
可能是一种矫枉过正, std::unique_ptr
应该是第一个要考虑的习惯用法。
struct EventWrapper {
std::unique_ptr<Event> event();
};
我故意改名为EventImpl
到EventWrapper
因为如果使用Impl
成语,应采用相反的关系:
struct EventImpl;
class Event {
std::unique_ptr<EventImpl> _impl;
};
class AEventImpl : public EventImpl {};
class BEventImpl : public EventImpl {};
class CEventImpl : public EventImpl {};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.