我正在編寫一個C++庫,所有類都使用工廠模式,即具有私有的空構造函數和私有的void init()
函數,它可以進行實例的實際初始化。可以由用戶庫進行實例化的類有一個公共靜態create()
函數執行以下操作:使用宏以工廠模式樣式替換「create()」函數API
static Class* create(int arg1, int arg2) {
Class* ret = new Class();
ret->init(arg1, arg2);
return ret;
}
也有幾類,其不得從庫外面被實例化,所以他們不提供公共create()
。
這些「內部類」確實有相互之間的一些關係friend
,這樣他們就可以實例對方。假設我想寫儘可能少的代碼可能,所以我想,以避免聲明和定義所有的內部類私人create()
功能,但我也想避免編寫
InternalClass* foo = new InternalClass();
foo->init();
所有的時間內類被實例化。相反,它會是不錯的一個(模板)函數或宏,它可以創建任何內部類只需要一行代碼,如
template<class T, typename ...Args> inline T* create(Args... args) {
T* ret = new T();
ret->init(args...);
return ret;
}
與上述功能(其將被定義爲在一個全局共享頭一個獨立的功能,因此,inline
關鍵字)的問題是,它繞過了類之間的friend
聲明並且因此將不會編譯。
另一方面,宏的問題在於,只要在宏內部有語句ret->init()
,它就不能「返回」指向該實例的指針,因此使用類似以下的宏將不會可能:
InternalClass* foo = CREATE(InternalClass, arg1, arg2);
最後,我的問題是:
是它在某種程度上可以創建一個可以在上面的方式調用(和不改變的所有init()
函數的返回類型一類的宏類型的指針,這的確會允許:#define CREATE(T, ...) (new T())->init(__VA_ARGS__)
)?
(請注意,這更是一個學術不是我已經實現與私營create()
功能的解決方案,這工作完全正常,似乎是「最乾淨」解決方案實用問題,我只是想知道是否有可能已經與宏的解決方案,太...)
我們用init嗎?爲什麼不在構造函數中進行初始化?另外,你的工廠方法的返回類型實際上是一樣的類,所以這家工廠是沒用的。 – SergeyA
如果你真的想要使用宏(你幾乎肯定不會),你可能需要像GCC的[語句表達式](https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs)。 html):#define CREATE(T,...)({auto * ret = new T; ret-> init(__ VA_ARGS__); ret;})'' – Justin