如何在 C++ 中初始化泛型基 class
How to initialize a generic base class in c++
我正在尝试重写一些旧代码以使其更加面向对象。以前我有一个 union of struct 调用,比如说 Event
union Event {
AEvent aEvent;
BEvent bEvent;
CEvent cEvent;
}
而这个Event
后来在结构
中使用
struct EventImpl {
... //some other members
Event event();
}
现在我正在尝试使用强大的shared_ptr
;
我创建了一个名为 BaseEvent
的新基地 class
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
这个名字有点误导,正如 Dmitry 指出的那样,EventWrapper
认为更合适。 :)
有很多不同的方法可以做到这一点。首先,您可以使用 std::variant
作为 OOP-aware 替代 union
:
using Event = std::variant<AEvent, BEvent, CEvent>;
另一种方法是使用动态多态性:您需要为所有 XEvent
类型定义一个基础 class:
class BaseEvent {};
class AEvent : public BaseEvent {};
动态多态的另一个方面是如何 return 值:通过原始指针、通过引用、智能指针等。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 {};
我正在尝试重写一些旧代码以使其更加面向对象。以前我有一个 union of struct 调用,比如说 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
这个名字有点误导,正如 Dmitry 指出的那样,EventWrapper
认为更合适。 :)
有很多不同的方法可以做到这一点。首先,您可以使用 std::variant
作为 OOP-aware 替代 union
:
using Event = std::variant<AEvent, BEvent, CEvent>;
另一种方法是使用动态多态性:您需要为所有 XEvent
类型定义一个基础 class:
class BaseEvent {};
class AEvent : public BaseEvent {};
动态多态的另一个方面是如何 return 值:通过原始指针、通过引用、智能指针等。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 {};