我有一個稍微噁心的設置,我試圖找出檢修的好方法。保留子類的中心列表,但避免靜態實例
我有一個class Fractal
與幾個純虛函數來做工作。每個實例也有一個人類可讀的名字。我想要構建一個所有這些子類的菜單,以便用戶可以在它們之間切換 - 但是,由於懶惰,我不想同時在源文件中定義每個實例,並在另一個實例中再次列出它們。換句話說,我想在運行時動態建立這個子類的列表。
我做了什麼(有工作)至今是:
- 定義
class FractalRegistry
這是一個std::map<std::string,Fractal*>
(其中鍵是實例名稱)的單封裝, - 有基地
Fractal
構造函數通過名稱向該註冊表註冊每個實例(並且爲了完整性,基地~Fractal
註銷它們), - 靜態地實例化每個基類(使用其名稱,這是一個構造函數參數)。
所以對於每一個新的分形我寫這樣的事情(轉述):
class SomeFractal : public Fractal {
public:
SomeFractal(std::string name, std::string desc) : Fractal(name,desc) {}
virtual void work_function(...) { ... }
}
SomeFractal sf_instance("Some fractal", "This is some fractal or other");
和實例添加到由基類構造函數中央列表,所以我並不需要列出它自己。
但是,這會導致靜態實例處於負載狀態,如果將此代碼移動到庫中,這似乎會消失。 (是的,我可以添加一個可怕的空函數每個編譯單元,所以我可以強制將其列入,或訴諸到鏈接弄虛作假如-Wl,--whole-archive
,但這些似乎並沒有像正確答案,無論是。)
是有更好的方法?我想我正在尋找的是一種編寫這些Fractal實現的方法 - 所有這些實現都有相同的接口,所以我認爲基類的子類將是理想的 - 並且保留並填充它們的中央註冊表,但不會離開我自己是靜態實例的地雷。
我錯過了什麼? 我應該說我已經和C一起工作了很多年,但並沒有真正的C++禪,所以很可能會有這樣的工作能夠做到讓我面對我的工作......(如果我正在編寫這個在C中,我會考慮編寫一個二階宏組合,它既聲明瞭一些函數指針,又用它們和分形的名稱和描述填充了一個表格,但這是一個更重要的事情,它看起來並不像適合C++)
編輯: 我所希望實現的是這使得它容易增加新的分形類型,並自動重新安排我的代碼的一種優雅的方式填充他們的中心名單,但不迫使程序員創建每個分形的靜態實例。
是那些子類應該是這樣的單身?例如,你不希望用戶能夠實例化一個或者你想要什麼?我無法弄清楚。 – Xeo 2011-05-28 23:54:48
我通常會放棄 - 無論使用哪種makefile技巧來構建和鏈接所有單個分形,還能夠爲註冊每個分形的實例的函數生成源代碼。從'main'中調用該函數,或者在庫函數中調用該函數,或者從FractalRegistry的構造函數中調用該函數,或者從執行查找的函數調用該函數(當然,檢查它當前還沒有被調用)。 – 2011-05-28 23:58:19
是否可以以「黑匣子」的形式將2-3行延伸到您的問題(即輸入和結果是什麼)。你的問題不清楚。 – iammilind 2011-05-29 06:02:03