私は Windows 用の GUI ライブラリを開発してきました (個人的なサイド プロジェクトとして、実用性は期待していません)。私のメイン ウィンドウ クラスでは、オプション クラスの階層を ( Named Parameter Idiomを使用して) セットアップしました。これは、いくつかのオプションが共有され、他のオプションが特定の種類のウィンドウ (ダイアログなど) に固有であるためです。
名前付きパラメーターのイディオムが機能する方法では、パラメーター クラスの関数は、呼び出されたオブジェクトを返す必要があります。問題は、階層内で、それぞれが異なるクラス (createWindowOpts
標準ウィンドウのcreateDialogOpts
クラス、ダイアログのクラスなど) でなければならないことです。すべてのオプション クラス テンプレートを作成することで、これに対処しました。次に例を示します。
template <class T>
class _sharedWindowOpts: public detail::_baseCreateWindowOpts {
public: ///////////////////////////////////////////////////////////////
// No required parameters in this case.
_sharedWindowOpts() { };
typedef T optType;
// Commonly used options
optType& at(int x, int y) { mX=x; mY=y; return static_cast<optType&>(*this); }; // Where to put the upper-left corner of the window; if not specified, the system sets it to a default position
optType& at(int x, int y, int width, int height) { mX=x; mY=y; mWidth=width; mHeight=height; return static_cast<optType&>(*this); }; // Sets the position and size of the window in a single call
optType& background(HBRUSH b) { mBackground=b; return static_cast<optType&>(*this); }; // Sets the default background to this brush
optType& background(INT_PTR b) { mBackground=HBRUSH(b+1); return static_cast<optType&>(*this); }; // Sets the default background to one of the COLOR_* colors; defaults to COLOR_WINDOW
optType& cursor(HCURSOR c) { mCursor=c; return static_cast<optType&>(*this); }; // Sets the default mouse cursor for this window; defaults to the standard arrow
optType& hidden() { mStyle&=~WS_VISIBLE; return static_cast<optType&>(*this); }; // Windows are visible by default
optType& icon(HICON iconLarge, HICON iconSmall=0) { mIcon=iconLarge; mSmallIcon=iconSmall; return static_cast<optType&>(*this); }; // Specifies the icon, and optionally a small icon
// ...Many others removed...
};
template <class T>
class _createWindowOpts: public _sharedWindowOpts<T> {
public: ///////////////////////////////////////////////////////////////
_createWindowOpts() { };
// These can't be used with child windows, or aren't needed
optType& menu(HMENU m) { mMenuOrId=m; return static_cast<optType&>(*this); }; // Gives the window a menu
optType& owner(HWND hwnd) { mParentOrOwner=hwnd; return static_cast<optType&>(*this); }; // Sets the optional parent/owner
};
class createWindowOpts: public _createWindowOpts<createWindowOpts> {
public: ///////////////////////////////////////////////////////////////
createWindowOpts() { };
};
動作しますが、ご覧のとおり、かなりの量の追加作業が必要です。各関数の戻り値の型の型キャスト、追加のテンプレート クラスなどです。
私の質問は、この場合、すべての余分なものを必要としない名前付きパラメーター イディオムを実装する簡単な方法はありますか?