問題描述
像我之前的許多人一樣,我正在嘗試讓我的派生類型自動注冊到我的工廠.我通讀了許多問題,并試圖專注于我在那里沒有找到的內容.
Like many before me, I'm trying so get my derived types to automatically register with my factory. I read through many question and tried to focus on what I didn't find there.
除了自動注冊之外,其他一切都運行良好.
I've got everything running nicely except the automatic registration.
我的目標:
- 自動注冊我的基類的任何派生類Base
- 只有我標記為可注冊 的課程
- 不僅是Base的直接子類
- 例如: Base -> Device -> Camera -> 網絡攝像頭
- 這將使使用 CRTP 如這個問題困難
- only classes I mark as registrable
- not only direct sub-classes of Base
- ex: Base -> Device -> Camera -> Webcam
- this would make using the CRTP like described in this question dificult
- 就像在這個問題中一樣,但我不確定這是否依賴于 CRTP
- like in this question, but I'm not sure if this is dependent on CRTP
我有什么:
template <class T>
class abstract_factory
{
public:
template < typename Tsub > static void register_class();
static T* create( const std::string& name );
private:
// allocator<T> is a helper class to create a pointer of correct type
static std::map<std::string, boost::shared_ptr<allocator<T> > > s_map;
};
- 模板化抽象工廠,std::string 作為鍵類型
- 抽象工廠擁有所有成員和方法靜態
- 使用typeid自動恢復類名(注冊時不需要文本名稱)
- 調用注冊:
abstract_factory
::register_class (); - templated abstract factory, with std::string as key type
- abstract factory has all members and methods static
- class name is recovered automatically with typeid (no need for text name when registering)
- registration by calling:
abstract_factory<Base>::register_class<MyDerived>();
registrator
:在class Derived.cpp
中靜態實例化的模板化類,應在其構造函數中調用abstract_factory::register_class
() - 永遠不會被調用或實例化
- 如果我在
main()
中創建一個Derived
的實例,這有效 -> 雖然有點違背了目的
registrator<Derived> class
: templateded class that is instantiated statically inDerived.cpp
and should callabstract_factory::register_class<Derived>()
in it's constructor- never gets called or instantiated
- if I make an instance of
Derived
inmain()
this works -> kinda defeats the purpose though
可以使用任何建議,無論大小,thanx.
Could use any advice, large or small, thanx.
推薦答案
我用單例帶成員注冊,基本上:
I use a singleton with a member for registration, basically:
template< typename KeyType, typename ProductCreatorType > class Factory { typedef boost::unordered_map< KeyType, ProductCreatorType > CreatorMap; ... };
使用 Loki 之后,我得到了一些類似的東西:
Using Loki I then have something along these lines:
typedef Loki::SingletonHolder< Factory< StringHash, boost::function< boost::shared_ptr< SomeBase >( const SomeSource& ) > >, Loki::CreateStatic > SomeFactory;
注冊通常使用宏完成,例如:
Registration is usually done using a macro such as:
#define REGISTER_SOME_FACTORY( type ) static bool BOOST_PP_CAT( type, __regged ) = SomeFactory::Instance().RegisterCreator( BOOST_PP_STRINGIZE( type ), boost::bind( &boost::make_shared< type >, _1 ) );
這種設置有很多優點:
- 適用于例如 boost::shared_ptr<>.
- 不需要為所有注冊需求維護一個龐大的文件.
- 對于創作者來說非常靈活,任何事情都非常順利.
- 宏涵蓋了最常見的用例,同時為替代方案敞開了大門.
調用 .cpp 文件中的宏就足以在靜態初始化期間在啟動時注冊類型.當類型注冊是靜態庫的一部分時,這很有效,在這種情況下,它不會包含在您的二進制文件中.將注冊編譯為我見過的庫的一部分的唯一解決方案是擁有一個巨大的文件,該文件將注冊明確作為某種初始化例程的一部分.相反,我現在所做的是在我的庫中創建一個客戶端文件夾,用戶將其作為二進制構建的一部分包含在內.
Invoking the macro in the .cpp file is then enough to get the type registered at start up during static initialization. This works dandy save for when the type registration is a part of a static library, in which case it won't be included in your binary. The only solutions which compiles the registration as a part of the library which I've seen work is to have one huge file that does the registration explicitly as a part of some sort of initialization routine. Instead what I do nowadays is to have a client folder with my lib which the user includes as a part of the binary build.
從您的要求列表中,我相信除了使用注冊器類之外,這可以滿足所有要求.
From your list of requirements I believe this satisfies everything save for using a registrator class.
這篇關于c ++派生類型的自動工廠注冊的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!
【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!
我嘗試過的(或想嘗試但不知道如何正確操作):