gpt4 book ai didi

c++ - 继承类的标记分派(dispatch)

转载 作者:搜寻专家 更新时间:2023-10-31 00:28:46 26 4
gpt4 key购买 nike

我有一些代码,其中有一个基类(我们称它为 foo),它具有由生成脚本创建的可变数量的派生类(在 10-500 之间)。目前,我们有一个函数可以通过将其名称作为字符串传递,然后使用巨大的 if/else 语句来找到正确的基类,从而创建一个新的基类。例如

if      (name == "P2_26") {add_module(new P2_26());}  
else if (name == "P4_30") {add_module(new P4_30());}
...

这会导致一个巨大的 if else block 。在我看来,这似乎是可以通过使用标签分派(dispatch)来简化的代码,但我在网上找到的每个示例都使用内置函数,例如已经定义了标签的迭代器,我无法插入到我的用例中。有没有办法简化这段代码?

最佳答案

分派(dispatch)的标签基于类型信息作为输入。从你的代码来看,你有一个字符串作为输入,它不能在运行时使用。
你的案例看起来更像是一个抽象工厂:

// Factory.h
class Base;

struct Factory {
using spawn_t = std::function<Base*()>;
using container_t = std::unordered_map<std::string, spawn_t>;

static container_t& producers() {
// This way it will be initialized before first use
static container_t producers;
return producers;
}

static Base* spawn(const std::string& name) {
auto it = producers().find(name);
if (it == producers().end()) return nullptr;
return it->second();
}
};

// Base.h
#define STR(x) #x
#define DEFINE_REGISTRATOR(_class_) \
DerivedRegistrator<_class_> _class_::_sRegistrator_(STR(_class_))

#define DECLARE_REGISTRATOR(_class_) \
static DerivedRegistrator<_class_> _sRegistrator_

template<typename T>
struct DerivedRegistrator{
DerivedRegistrator(const std::string& name) {
Factory::producers()[name] = [](){ return new T(); };
}
};

class Base {
// ...
};

然后生成的文件应该包括:

// Derived1.h
class Derived1 : public Base {
DECLARE_REGISTRATOR(Derived1);
// ...
};

// Derived1.cpp
DEFINE_REGISTRATOR(Derived1); // Will register automatically

此解决方案将在程序启动时自动注册所有类,这更像您之前的做法。


更新。

要使用它,您只需用这一行替换所有 if-else 代码:

add_module(Factory::spawn(name));

或者如果您无法在 add_module 中处理 nullptr:

Base* ptr = Factory::spawn(name);
if (ptr) {
add_module(ptr);
}

感谢D Drmmr为了使这段代码更好。

关于c++ - 继承类的标记分派(dispatch),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43853667/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com