Section I ================ general function pointer usage
function pointer can point to
1. general c-style function
2. template c-style function
3. general c++ static member function, which is totally the same with c-style function
4. c++ static member function which was used to delegate general non-static member function.
the benefit of this usage is, we can use function pointer to base class to delegate member function of
derived class.
all usage can be found in the following example. run it and get a feeling.
#include
#include
#include
#include
using namespace std;
class Base;
class A;
//c or c++ static member function
int (*function_pointer_c_style)(int,int);
//c++ non-static member function
int (A::*function_pointer_class_non_static_style)(int,int);
//c++, use static-style member function to delegate non-static member function
int (*function_pointer_class_static_delegate_style)(void*, int,int);
int sum(int a, int b)
{
cout << "call non-template c-style function" << endl;
cout << a << " + " << b << " = " << a + b << endl;
cout << endl;
}
template
int sum(A a, B b)
{
cout << "call template c-style function" << endl;
cout << a << " + " << b << " = " << a + b << endl;
cout << endl;
}
template
int multi(T a, int b)
{
cout << "function pointer which point to template function" << endl;
cout << a << " * " << b << " = " << a * b << endl;
cout << endl;
}
class Base
{
public:
int SumNonStatic( int a, int b)
{
cout << "call base class non-static member function" << endl;
cout << "Base class: " << a << " + " << b << " = " << a + b << endl;
cout << endl;
}
};
class A : public Base
{
public:
static int Sum(int a, int b)
{
cout << "call class static member function" << endl;
cout << a << " + " << b << " = " << a + b << endl;
cout << endl;
}
int SumNonStatic( int a, int b)
{
cout << "call class non-static member function" << endl;
cout << "Derived class: " << a << " + " << b << " = " << a + b << endl;
cout << endl;
}
static int Delegate(void*p, int a, int b)
{
//base to derived, use static_cast but dynamic_cast
A* pa = static_cast(p);
cout << "use static member function to delegate non-static member function. " << endl;
pa->SumNonStatic(a, b);
cout << endl;
}
};
int main()
{
function_pointer_c_style = sum;
//the full format should be (*funtion_pointer)(para1, para2... )
//the short format function_pointer(para1, para2...) is also right in C
//but in c++, we must use (object.*function_pointer)(para1, para2...)
(*function_pointer_c_style)(3,4);
function_pointer_c_style = multi
function_pointer_c_style(3,4);
function_pointer_c_style = &A::Sum;
function_pointer_c_style(3,4);
function_pointer_class_non_static_style = &A::SumNonStatic;
A a;
(a.*function_pointer_class_non_static_style)(3,4);
function_pointer_class_static_delegate_style = &A::Delegate;
function_pointer_class_static_delegate_style((void*)(&a), 3, 4);
return 0;
}
@see for detailed instruction
Section II ================ std::mem_fun etc...
in following section, we will show the std::mem_fun and some related concept, such as bind1st and bind2st ..
the mechanisms of mem_fun is similar to
std::mem_fun or std::mem_fun_ref
1. only support non-parameter or one-parameter function, also bind1st, bind2nd ...
2. if we want to support arbitrary parameter, we can use to
to customerize "mem_fun" of our-selves. but i recommend boost::function and boost::bind, which is
very easy to use. see Section III
#include
#include
using namespace std;
class A
{
public:
int NonPara()
{
cout << "member function without parameter!" << endl;
cout << endl;
return 0;
}
int OnePara(int para)
{
cout << "member function with one parameter:" << para << endl;
cout << endl;
return 0;
}
int TwoPara(int a, int b)
{
cout << "member function with two parameter:" << endl;
cout << a << " + " << b << " = " << a + b << endl;
cout << endl;
return 0;
}
int MultiPara(int a, int b, int c)
{
cout << "member function with multi parameter:" << endl;
cout << a << " + " << b << " + " << c << " = " << a + b + c << endl;
cout << endl;
return 0;
}
};
int main()
{
mem_fun_t
//mem_fun_ref is similar to mem_fun, except that
//mem_fun_ref require reference to object as its first parameter
mem_fun_ref_t
mem_fun1_t
A a;
std_mem_fun_non_para(&a);
std_mem_fun_non_para_ref(a);
std_mem_fun_one_para(&a, 3);
//show bind1st.
//next time we needn't pass object as first parameter, just pass the real para
//such as call member function directly
std::binder1st
bind1st(std_mem_fun_one_para, &a);
cout << "use bind1sh to bind object pointer" << endl;
std_mem_fun_non_para_with_object_bound(2);
cout << endl;
return 0;
}
Section III ================ boost::function and boost::bind
the above difficulty can be easily solved by boost::function. boost::function is extended mem_fun,
and boost::bind is extended bind1st ...
see follow links:
//
//
#include
#include
#include
#include
using namespace std;
class A
{
public:
int NonPara()
{
cout << "member function without parameter!" << endl;
cout << endl;
return 0;
}
int OnePara(int para)
{
cout << "member function with one parameter:" << para << endl;
cout << endl;
return 0;
}
int TwoPara(int a, int b)
{
cout << "member function with two parameter:" << endl;
cout << a << " + " << b << " = " << a + b << endl;
cout << endl;
return 0;
}
int MultiPara(int a, int b, int c)
{
cout << "member function with multi parameter:" << endl;
cout << a << " + " << b << " + " << c << " = " << a + b + c << endl;
cout << endl;
return 0;
}
};
int main()
{
//we don't use typedef for easy read. typedef should be used in practice
A a;
//use boost::function only, Note: A* must be a first parameter
boost::function
member_function_with_boost_function_only(&a, 3, 4, 5 ); // object as first parameter when call it
//use boost::function and boost::bind. Note: returned function object have no A* as first para
boost::function
member_function_with_boost(3,4,5);//call directly, similar to member function
return 0;
}