- ベストアンサー
C++ 振る舞いの動的な変更
- C++で複数の処理をひとつのインターフェースでモード切り替えできる方法について
- クラスや関数ポインタを使用して処理をまとめる方法が悩ましい
- 名前空間を使用してstaticなメンバを持たせることも考慮している
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
質問の意図を理解できていないのかもしれないですが、単にstatic関数をやめて通常の仮想関数にすればよいのではないでしょうか。 たとえば、実装側をこのように変更し class SuperClass { public: virtual void method_1() = 0; virtual void method_2() = 0; }; class classA : public SuperClass { public: virtual void method_1() { cout << "A::method_1" << endl; } virtual void method_2() { cout << "A::method_2" << endl; } }; class classB : public SuperClass { public: virtual void method_1() { cout << "B::method_1" << endl; } virtual void method_2() { cout << "B::method_2" << endl; } }; 利用側では、 auto_ptr<SuperClass> obj; obj.reset( new classA() ); obj->method_1(); // classA::method_1が呼び出される obj->method_2(); obj.reset( new classB() ); obj->method_1(); // classB::method_1が呼び出される obj->method_2(); という感じにするのが一番ではないかと思います。 どうしてもstaticクラスを使いたいなら class classA { public: static void method_1() { cout << "A::method_1" << endl; } static void method_2() { cout << "A::method_2" << endl; } }; class classB { public: static void method_1() { cout << "B::method_1" << endl; } static void method_2() { cout << "B::method_2" << endl; } }; class StaticClassCaller { public: virtual void method_1() {}; virtual void method_2() {}; }; template<class T> class StaticClassCallerImpl : public StaticClassCaller { public: virtual void method_1() { return T::method_1(); } virtual void method_2() { return T::method_2(); } }; // 利用側 auto_ptr<StaticClassCaller> obj; obj.reset( new StaticClassCallerImpl<classA>() ); obj->method_1(); obj->method_2(); obj.reset( new StaticClassCallerImpl<classB>() ); obj->method_1(); obj->method_2(); とかどうでしょう。
その他の回答 (2)
- Tacosan
- ベストアンサー率23% (3656/15482)
すみません, 「virtual なメンバ関数を持つオブジェクトの配列を持つ」ではダメですね. 「virtual なメンバ関数を持つオブジェクトへのポインタの配列を持つ」にしないと, virtual の意味がないっす.
- Tacosan
- ベストアンサー率23% (3656/15482)
まず「static なメンバ関数は virtual にできない」ことに注意してください. んで, やり方としてはいろいろあります. たとえば ・各関数ごとに if で切り分ける: 「アホ」といわれるかもしれない. 「どのモードでどのクラス (ないし名前空間) の関数を呼び出すか」はプログラマの責任. ・各関数ごとに「呼び出すべき関数の配列」を作っておく: 上よりはきれいになる. 「どのモードで~」は同じ. ・virtual なメンバ関数を持つオブジェクトの配列を持つ: 当然だが「オブジェクトを作ることができる」必要があるのでクラスに限定 (名前空間ではダメ). 「どの関数を呼び出すか」については統一できる. くらいは思いつく.
お礼
回答ありがとうございます。 そうですね、難しく考えずに、仮想関数で切り替えてやれば問題なさそうですね。 モードは任意数の切り替えが考えられるため、配列で管理しようと思います。 シングルトンパターンと組み合わせてやれば何とかなりそうです。