我有一个C ++工厂函数,它将用于实例化某些抽象类派生的具体类。
从代码操作的角度来看,这些具体类的实际英文名称并不重要。假设它们是不同类型的“事件”,派生自“AbstractEvent”类。出于代码函数的目的,派生类的实际名称无关紧要,因为它们都会在实例化时生成某种唯一的数字ID,这将是其他模块引用它们的方式,这只能用于对抽象类型的引用,而不是任何特定的具体类。
从代码维护的角度来看,对于编码人员来说,知道是否某个类或方法接受一个模板化的“FooEvent”与一个int一起工作或者一个模板化的“BarEvent”与一个浮点数,因此在使用API时,用户可以使用一些人类可读的术语。
有没有“规范”的方法来实现这一目标?如果解决方案不会产生任何运行时开销,那将是更可取的。
答案 0 :(得分:1)
constexpr字符串标识符怎么样:
#include <iostream>
#include <string>
#include <memory>
struct EventBase
{
virtual const std::string& type() const = 0;
virtual ~EventBase() = default;
};
template<const char* type_name>
struct EventModel : EventBase
{
const std::string& type() const override {
static const std::string _ { type_name };
return _;
}
};
constexpr char hello[] = "hello";
constexpr char world[] = "world";
int main(int argc, const char * argv[]) {
auto p1 = std::make_unique<EventModel<hello>>();
auto p2 = std::make_unique<EventModel<world>>();
std::cout << p1->type() << std::endl;
std::cout << p2->type() << std::endl;
return 0;
}
现在您有多种选择消息类型的选项:
bool is_hello_slow(const EventBase& e)
{
return e.type() == hello;
}
bool is_hello_medium(const EventBase* pe)
{
return dynamic_cast<const EventModel<hello>*>(pe);
}
template<class Event>
bool is_hello_compile_time(const Event&) {
return std::is_base_of<EventModel<hello>, Event>();
}