在C++中是否可以遍历Abstract类的所有子类?

Ste*_*ndl 4 c++ macros template-meta-programming

我在C++中有一个带有几个子类的抽象类.

是不是通过Macros或模板元编程可以做到这样的事情:

foreach subclass of Base:
  mymap[subclass::SOME_CONSTANT] = new subclass();
Run Code Online (Sandbox Code Playgroud)

Mat*_* M. 7

你不能.

显然,你想要的是Factory(或许Abstract Factory).

在C++中,您可以设置Factory类并注册构建器.

class FooFactory
{
public:
  typedef std::function<Foo*()> Builder;

  /// returns true if the registration succeeded, false otherwise
  bool Register(std::string const& key, Builder const& builder) {
    return map.insert(std::make_pair(key, builder)).second;
  }

  /// returns a pointer to a new instance of Foo (or a derived class)
  /// if the key was found, 0 otherwise
  Foo* Build(std::string const& key) const {
    auto it = _map.find(key);
    if (it == _map.end()) { return 0; } // no such key
    return (it->second)();
  }

private:
  std::map<std::string, Builder> _map;
};
Run Code Online (Sandbox Code Playgroud)

您可以创建此工厂的单例,在库加载期间注册派生类,这对于类似插件的体系结构很方便:

FooFactory& GetFooFactory() { static FooFactory F; return F; }
Run Code Online (Sandbox Code Playgroud)

你可以准备一个方便的建设者:

template <typename Derived>
Foo* fooBuilder() { return new Derived(); }
Run Code Online (Sandbox Code Playgroud)

然后人们应该在工厂注册他们的派生类:

static const bool registeredBar =
    GetFooFactory().Register("Bar", fooBuilder<Bar>);
Run Code Online (Sandbox Code Playgroud)

注意:工厂应该是一个单身人士并不是强制性的,尽管这里不那么邪恶,因为一旦图书馆的负荷结束,它就是不变的.

注意:对于正确的插件体系结构,您需要使用RAII(而不是bool)来处理库卸载时的注销.但这种情况更为罕见.