我的項目使用自注冊類有兩種方式:一種是實現工廠模式,它允許迭代這些類的映射,其實現幾乎完全類似於C++ how safe are self registering classes?中描述的實現;另一種是將巨大的開關語句分離成對象圖。在後一種情況下,我剛剛創建了一個基類和一組派生類,然後我在源文件中用靜態對象實例化了每個派生類,而類的構造函數將自己註冊到一個映射中。替代自注冊類
現在我試圖將我的應用的邏輯部分移動到靜態庫中,並在兩個子項目中使用這個庫(我使用Qt,Qt Creator和gcc)。這樣做之後,除非我在某處明確地實例化這些類,否則上述類都不起作用。
所以,我正在尋找任何解決方法。實際上,另一個問題正在出現:使用自注冊技術在C++中設計應用程序是否是一個非常不好的內容?
編輯:我被要求舉一個例子。這裏被簡化代碼:
// Class for storing actions
class ActionBase;
class SomeObject;
class ActionMap
{
public:
ActionMap();
static void registerAction(int n, ActionBase* action) {}
void performAction (SomeObject* object, int action) {
m_actions[action]->perform(object);
}
private:
std::map<int, ActionBase*> m_actions;
};
// Action class - action.h
#include "actionmap.h"
class SomeObject;
class ActionBase
{
public:
ActionBase(int n, ActionBase* action) {ActionMap::registerAction(n, action); }
virtual ~ActionBase() = 0;
virtual void perform(SomeObject* object) = 0;
};
template<int N>
class Action : public ActionBase
{
public:
Action() : ActionBase(N, this) {}
};
template<>
class Action<1> : public ActionBase
{
public:
Action() : ActionBase(1, this) {}
void perform(SomeObject* object)
{
// Do something
}
};
我現在可以創建行動的源文件中的一些操作對象,是這樣的:
// action.cpp
// #include "action.h"
static Action<1> action1;
重組項目之後,我要在我的子項目某處創建動作1變量明確地可以使用它,例如在main.cpp中。
更新:似乎Angew幫助我部分解決了第二個問題。我已經刪除了一個免費的空函數,並在action.cpp中定義了它。在應用程序中的某處調用強制執行操作對象的初始化。
_「上述任何類都不起作用,除非您需要更多地解釋這一點並嘗試包含[MCVE] –
@RichardCritten,這很可能是鏈接器刪除包含註冊實例的目標文件,因爲沒有人引用它。如果你問我,破壞行爲,但我們在這裏。 – Quentin
@Quentin不一定。不要忘記,在C++中,文件範圍變量只能保證在執行該文件的任何代碼之前被初始化,但是它們可以在'main'啓動後被初始化。 – Angew