問題点と解決したい点
次のコードを見て下さい。
C++
1enum class Graphic { A, B, C }; 2 3class Base { 4protected: 5 // template <typename U = decltype(this)> 6 // U は Derived になって欲しい… 7 Base() { 8 ResourceManager.preload(U::Graphics); 9 } 10 DrawGraphic(Graphic graphic) { 11 Draw(ResoureManager.getGraphicHandle(graphic)); 12 } 13}; 14class Derived : Base { 15public: 16 static constexpr auto Graphics = {Graphic::B, Graphic::C}; 17 void exec() { 18 DrawGraphic(Graphic::A); // コンパイル時エラーにしたい 19 DrawGraphic(Graphic::B); // 成功 20 DrawGraphic(Graphic::C); // 成功 21 } 22};
このような感じで、画像はA,B,Cの全3種類あり、実際にそれらのリソース管理(読み込み、破棄等)はResourceManagerに任せています。
このとき、Base から派生したすべてのクラスは、そのクラス内で使用する画像の一覧を何らかの形で持っており、必ずコンストラクタで ResourceManager の preload に渡したい。
また、DrawGraphic についてはどの派生先クラスでも同じように Draw するため、Base で定義しています。
Graphics の型は auto(std::initializer_list<Graphic>) になっていますが、なんでも良いです。
とにかく、画像B, C のみが使えることを明示できれば良いです。
質問
どのように基底クラスのコンストラクタに、派生クラスが使用するリソースを伝えれば、DrawGraphic 関数の呼び出しの際に、Graphic::A に対してコンパイル時エラーを生成できますか。
蛇足
そもそも、やることが共通しているからといって、継承で解決しようとするのが間違いですか?
クラス定義の際に、継承先のクラスのコンストラクタでいちいち preload を書いていると忘れる可能性が高いし、その他にやることが増えたり減ったりするかもしれないので、基底クラスでやろうと思いましたが…
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/06/28 10:53
2020/06/29 02:26