• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:C++ 振る舞いの動的な変更)

C++ 振る舞いの動的な変更

このQ&Aのポイント
  • C++で複数の処理をひとつのインターフェースでモード切り替えできる方法について
  • クラスや関数ポインタを使用して処理をまとめる方法が悩ましい
  • 名前空間を使用してstaticなメンバを持たせることも考慮している

質問者が選んだベストアンサー

  • ベストアンサー
  • qwertfk
  • ベストアンサー率67% (55/81)
回答No.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(); とかどうでしょう。

miya_99
質問者

お礼

回答ありがとうございます。 そうですね、難しく考えずに、仮想関数で切り替えてやれば問題なさそうですね。 モードは任意数の切り替えが考えられるため、配列で管理しようと思います。 シングルトンパターンと組み合わせてやれば何とかなりそうです。

その他の回答 (2)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

すみません, 「virtual なメンバ関数を持つオブジェクトの配列を持つ」ではダメですね. 「virtual なメンバ関数を持つオブジェクトへのポインタの配列を持つ」にしないと, virtual の意味がないっす.

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

まず「static なメンバ関数は virtual にできない」ことに注意してください. んで, やり方としてはいろいろあります. たとえば ・各関数ごとに if で切り分ける: 「アホ」といわれるかもしれない. 「どのモードでどのクラス (ないし名前空間) の関数を呼び出すか」はプログラマの責任. ・各関数ごとに「呼び出すべき関数の配列」を作っておく: 上よりはきれいになる. 「どのモードで~」は同じ. ・virtual なメンバ関数を持つオブジェクトの配列を持つ: 当然だが「オブジェクトを作ることができる」必要があるのでクラスに限定 (名前空間ではダメ). 「どの関数を呼び出すか」については統一できる. くらいは思いつく.

関連するQ&A

専門家に質問してみよう