自動類註冊是一種常見的任務,在這裏一個常見的問題在計算器上:可擴展的自動化類註冊在C++中的C++
Register an object creator in object factory
Somehow register my classes in a list
automatic registration of object creator function with a macro
c++ automatic factory registration of derived types
基本目標是註冊呃類自動與一些註冊表或工廠,以便它可以在以後每個類的一些工作。
這是一個非常成熟的技術,被Google Test(http://code.google.com/p/googletest)等圖書館使用,可以自動註冊Test類的子類,以便每個測試都可以自動實例化並在測試執行期間運行。
註冊可以通過實例化一個靜態註冊器類來實現,註冊器類的構造函數執行註冊,或者通過巧妙使用CRTP並將註冊代碼放入基類構造器或任何你喜歡的東西(上面的鏈接提供了幾種不同的可能技術)。
但是,當我實施這些技術時,我發現它們的比例很差。如果我在Google Test中有10,000個TEST宏調用,編譯和鏈接就會停頓(MSVC 2010),並且二進制大小會爆炸。如果我以另一種方式實現這一點,則使用具有靜態註冊器的10,000個子類,我會看到相同的行爲。
例如,考慮簡化的例子:共有10000個自動生成的註冊電話
#include <iostream>
#include <string>
class Base {
public:
Base(const std::string& Name_) : Name(Name_) { ; }
~Base() { ; }
virtual std::string GetName() const { return Name; }
virtual void DoSomething() = 0;
private:
std::string Name;
};
class Registry {
public:
static Registry& GetInstance() {
static Registry* Instance = new Registry();
return *Instance;
}
void Register(const Base* b) {
std::cout << "Registered class " << b->GetName() << std::endl;
}
private:
Registry() { ; }
~Registry() { ; }
};
class Registrar {
public:
Registrar(const Base* b) {
Registry::GetInstance().Register(b);
}
~Registrar() { }
};
#define REGISTER(CLASS) \
class CLASS : public Base { \
public: \
CLASS(const std::string& Name) : Base(Name) { ; } \
virtual void DoSomething(); \
private: \
static Registrar m_Registrar; \
}; \
Registrar CLASS::m_Registrar(new CLASS(#CLASS)); \
void CLASS::DoSomething()
int main(int argc, char** argv)
{
return 0;
}
REGISTER(Class1)
{
std::cout << "Doing something in Class1" << std::endl;
}
REGISTER(Class2)
{
std::cout << "Doing something in Class2" << std::endl;
}
[...]
。
有沒有一個根本原因,爲什麼這不會擴展好?編譯器會扼殺10000個類嗎?在MSVC 2010下編譯上述代碼在一臺相當快的機器上花費了將近兩分鐘的時間,並且生成了一個大小超過5 MB的二進制文件。如果我與谷歌測試類似,我會看到相同的結果。
請注意'class'和'object'之間的區別。此代碼不**註冊類(也不應該),它註冊**對象**。 –
謝謝皮特。就我的目的而言,對於Google Test,我們將會有一對一的映射,因此我可以選擇一種技術來註冊,但您的觀點已被充分利用。 – DSII
不,如果沒有**的努力,你不能註冊課程。 –