假设您的 ID 为 0、1、2、3,...,您可以做的是创建一个std::map
将每个消息 ID 映射到一个函数指针,该函数指针指向为该 ID 创建正确类型的对象的命名构造函数。
class BaseClass {
private:
typedef (BaseClass*) (*NamedConstructor) (SomeType &);
// The map.
static std::map<int, NamedConstructor> id_to_constructor;
public:
// All the possible message types.
enum MessageType {
FooMsg = some_value,
BarMsg = some_other_value,
... // potentially a whole lot more
};
// Add a named constructor to the map.
static void add_handler (MessageType id, NamedConstructor cotr) {
// Error handling such as duplicates left as an exercise to the user.
id_to_constructor[id] = cotr;
}
// Function that applies the map.
static void handle_message (int id, SomeType & my_file) {
// Error handling such as a missing entry left as an exercise to the user.
NamedConstructor cotr = id_to_constructor[id];
cotr (my_file);
}
...
};
class Foo : public BaseClass {
public:
static BaseClass* create_foo (SomeType & my_file) {
return new Foo (my_file); // Or use a smart pointer.
}
// Member data and member functions elided.
...
};
class Bar : public BaseClass {
public:
static BaseClass* create_bar (SomeType & my_file) {
return new Bar (my_file); // Or use a smart pointer.
}
// Member data and member functions elided.
...
};
您将需要一些机制来使用该方法 注册命名构造函数Foo::create_foo()
等。如果您有 500 种消息类型,那就是 500 行代码,但它将是直线(没有 if,没有 switch)代码。Bar::create_bar()
BaseClass
add_handler
另一种方法是带有 500 个案例的 switch 语句。叶赫。
那么为什么是地图而不是矢量呢?如果您知道 ID 将变为 0、1、2、...,那么向量就可以了。如果你有差距怎么办?如果设计上有很大的差距怎么办?例如,可以对消息 ID 进行汉明编码,以减少错误。