class Car
{
       typedef void(*SIGNAL)();
       SIGNAL signal;
public:
       Car(SIGNAL s = 0) : signal(s) { }
       void SpeedUp( int speed )
       {
             cout << "Speed : " << speed << endl;
             if( speed > 100 && signal != 0 )
                    signal();    // 외부에알린다.
       }
};
void Police()
{
       cout << "Police Start.." << endl;
}
void main()
{
       Car c(Police);
       c.SpeedUp(100);
       c.SpeedUp(200);
}
/////////////////////////////////////////////////////////////
// 1. callback을 담당 할 클래스를 만들자. - 함수포인터를 관리하는 객체
class delegate
{
       typedef void(*SIGNAL)();
       SIGNAL signal;
       vector<delegate*> del_list;
public:
       delegate( SIGNAL s ) : signal(s) {}
       void Add( delegate* p ) { del_list.push_back( p ); }
       void Remove( delegate* p ) { }
       
       void Invoke()
       {
             if( signal != 0 ) signal();
             for( int i = 0; i < del_list.size(); ++i )
                    del_list[i]->Invoke();
       }
       // 연산자 재정의
       delegate* operator+=(delegate* p)
       {
             Add(p);
             return this;
       }
       void operator()()
       {
             Invoke();
       }
};
//----------------------------------------------------------
void foo() { cout << "foo" << endl; }
void main()
{
       delegate d1(foo);
       delegate d2(foo);
       delegate d3(foo);
       d3 += new delegate(foo);
       d3.Add( new delegate(foo) );
       d2 += &d3;
       d1.Add( &d2 );
       d1.Invoke();
       cout << endl;
       d1();
}
/////////////////////////////////////////////////////////////////
// 2. callback을 담당 할 클래스를 만들자. - 함수포인터를 관리하는 객체
class delegate
{
       typedef void(*SIGNAL)();
       SIGNAL signal;
       vector<delegate*> del_list;
public:
       delegate( SIGNAL s ) : signal(s) {}
       void Add( delegate* p ) { del_list.push_back( p ); }
       void Remove( delegate* p ) { }
       
       void Invoke()
       {
             if( signal != 0 ) signal();
             for( int i = 0; i < del_list.size(); ++i )
                    del_list[i]->Invoke();
       }
       // 연산자재정의
       delegate* operator+=(delegate* p)
       {
             Add(p);
             return this;
       }
       void operator()()
       {
             Invoke();
       }
};
//----------------------------------------------------------
class Car
{
public:
       delegate del;
public:
       Car() : del(0) { }
       void SpeedUp( int speed )
       {
             cout << "Speed : " << speed << endl;
             if( speed > 100  /*&& del != 0*/ )
                    del(); // 외부에알린다.
       }
};
void Police()
{
       cout << "Police Start.." << endl;
}
void main()
{
       Car c;
       c.del += new delegate(Police);
       c.del += new delegate(Police);
       c.SpeedUp(100);
       c.SpeedUp(200);
}