5

短縮版:

要点は、インスタンスの (複雑な) 状態は、クラスの定義の外にある関数によって変更できるということです。そのようなクラスは、多くの状態でクラス定義を汚染することなく、あらゆる種類の内部状態を持つように拡張できます。セッター。

次のコードを想定します。

 class bar
 {
      virtual void ChangeState()=0;
 }
 class foo:bar
 {
 private:
      int b;
 public:
      void ChangeState() {b=3;}
 }

私がやりたいのは、さまざまな関数を作成し、実行時にそれらを関数に渡すことです。

foo.ChangeState(); //b is 3 now
void foo::(?)ChangeState2(){ b=2; };
foo.ChangeState=ChangeState2;
foo.ChangeState(); //b is 2 now

ハックを使用せずに、そのような構造を C++ で実装できますか?

4

3 に答える 3

3

たぶん、これが役立ちます:

#include <iostream>

namespace so
{

class B
{
  friend void change_1( B * );
  friend void change_2( B * );
  friend void change_3( B * );

  int i;
 public:
  B() : i{ 0 } {}

  void change_state( void (*_function)( B * ) )
  {
   _function( this );

   std::cout << i << std::endl;
  }
};

void change_1( B * _object )
{
 _object->i = -1;
}
void change_2( B * _object )
{
 _object->i = -2;
}
void change_3( B * _object )
{
 _object->i = -3;
}

} //namespace so

int main()
{
 so::B b{ };

 b.change_state( so::change_1 );
 b.change_state( so::change_2 );
 b.change_state( so::change_3 );

 return( 0 );
}
于 2013-08-21T20:13:03.127 に答える
2

簡単な答え: それは不可能です。

できることは、複数のクラスを定義し、実行時の条件に基づいてそれらの中から選択することです。もちろん、そのオブジェクトは完全なクラスである必要はありません。次のようにすることもできます。

 class foo: public bar
 {
    private:
       class ChangeState
       {
         public:
           virtual void DoChangeState(foo *f) = 0;
       };
       class ChangeState2
       {
         public:
           virtual void DoChangeState(foo *f) { f->b = 2 } ;
       };
       class ChangeState3 : public ChangeState
       { 
         public:
           virtual void DoChangeState(foo *f) { f->b = 3 } ;
       };
   ChangeState *stateChanger

   public:
      foo() { stateChanger = new ChangeState3; }
      void SetStateChange2() { delete stateChanger; stateChanger = new ChangeState2; }
      ~foo() { delete stateChanger; }
      void ChangeState() { stateChanger->DoChangeState(this); }
};

このテーマには他にもバリエーションがあると思います (おそらくスマート ポインターを使用する必要があります)。

于 2013-08-21T20:07:09.837 に答える
1

記述した構文を使用して、実行時に動作を変更することはできません。ただし、必要に応じて、関数ポインターを使用して同様のものを取得できます。

しかし、あなたが正しく達成しようとしていることを理解していれば、戦略パターンの実装を検討します

于 2013-08-21T20:13:24.307 に答える