5

Short Version:

The main point is that the (complex) state of an instance can be changed by functions that are outside the definition of the class, as such the class can be extended to have all sorts of internal states without polluting the class defintion with many state-setters.

Assume the following code:

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

What I would like to do is create different functions, then pass them to the function, at runtime, something like

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

Can such a construct be implemented in C++, without the use of hacks?

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 回答