我在C++中有一個抽象類,有幾個子類。在C++中循環遍歷Abstract類的所有子類是否可能?
是它在某種程度上由宏或模板元編程可以做這樣的事情:
foreach subclass of Base:
mymap[subclass::SOME_CONSTANT] = new subclass();
我在C++中有一個抽象類,有幾個子類。在C++中循環遍歷Abstract類的所有子類是否可能?
是它在某種程度上由宏或模板元編程可以做這樣的事情:
foreach subclass of Base:
mymap[subclass::SOME_CONSTANT] = new subclass();
不,你不能。
你想要什麼,顯然是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;
};
您可以創建這個工廠的單,庫負荷,這是非常方便的插件式的建築風格中註冊的派生類:
FooFactory& GetFooFactory() { static FooFactory F; return F; }
而且你可以準備一個方便的建設者:
template <typename Derived>
Foo* fooBuilder() { return new Derived(); }
那麼,人們有望在工廠登記他們的派生類:
static const bool registeredBar =
GetFooFactory().Register("Bar", fooBuilder<Bar>);
注意:工廠應該是單身人士還不是強制性的,儘管它不像這裏那麼邪惡,因爲一旦圖書館的負載結束,它就是不變的。
注意:對於正確的插件架構,您需要使用RAII(而不是bool)來處理庫卸載時的註銷。雖然這很少見。
C++不允許迭代類型。也枚舉枚舉成員是不可能的。看到這個:
enum Color
{
red,
green,
blue=5,
yellow
};
此外,C++編譯器獨立編譯編譯單元。您可以對它進行映像,以便在編譯基類實現時無法知道該類有時會被繼承。
不可以。編譯器無法知道您是否在其他翻譯單元中添加了另一個子類。或者鏈接到添加子類的庫。 – Erik 2011-03-27 17:03:05
不,如果你告訴我們你爲什麼要這樣做,我們可以提供一個解決方案。 – fredoverflow 2011-03-27 17:03:21
雖然,AFAIK,這可能無法進行手動註冊(這是首選和安全的方法),但您可以使用[Typelists](http://www.drdobbs.com/generic-programmingtypelists-and-applica/184403813 )來緩解繁瑣的註冊碼。 – 2013-04-06 06:22:59